开发者社区> 问答> 正文

ErrCode43008ErrMsg参数需要multipart类型

钉钉上传媒体文件接口https://oapi.dingtalk.com/media/upload,请求之后一直报错=>{ErrCode:43008,ErrMsg:参数需要multipart类型},http头已经加入了"multipart/form-data; boundary=" + boundary,还是一样的错,看demo,怎么看都没办法用起来,这个接口到底要怎么调用?论坛上已经有几个同样的问题了,却没有得到一个可用的答案?语言用的是c#.

展开
收起
如_意 2016-07-19 16:05:05 11042 0
5 条回答
写回答
取消 提交回答
  • ReErrCode43008ErrMsg参数需要multipart类型
    使用的六楼的函数,结果还是“43008ErrMsg参数需要multipart类型”。
    2016-12-22 15:22:10
    赞同 展开评论 打赏
  • 2016-07-21 17:11:44
    赞同 展开评论 打赏
  • ReErrCode43008ErrMsg参数需要multipart类型
    经过不断的尝试总算找到了不太完整的解决方法,代码如下
    /// <summary>
            ///POST文件
            /// </summary>
            /// <param name="url"></param>
            /// <param name="timeout"></param>
            /// <param name="fileKeyName">比如钉钉上传媒体文件使用的是media,该值用于服务端接收到数据时读取该keyname之后相关的数据。</param>
            /// <param name="fileBuffer">文件数据</param>
            /// <param name="fileName">文件名</param>
            /// <returns></returns>
            public static string Post(string url,
                                      string fileKeyName,
                                      byte[] fileBuffer,
                                      String fileName,
                                      int timeout)
            {

                var boundary = SecurityHelper.GenerateRadomStr();
                WebClient webClient = new WebClient();
                webClient.Headers.Add("Content-Type", string.Format("multipart/form-data; boundary={0}", boundary));
                string fileFormdataTemplate =
                                "\r\n--" + boundary +
                                "\r\nContent-Disposition:form-data;name=\"{0}\";filename=\"{1}\"" +
                                "\r\nContent-Type:application/octet-stream" +
                                "\r\n\r\n";
                string formDataHeader = String.Format(fileFormdataTemplate, "media", fileName);
                byte[] formDataHeaderBuffer = Encoding.UTF8.GetBytes(formDataHeader);

                string begin = $"--{boundary}\r\n";
                byte[] beginBuffer = Encoding.UTF8.GetBytes(begin);

                string end = $"\r\n--{boundary}--\r\n";
                byte[] endBuffer = Encoding.UTF8.GetBytes(end); ;

                byte[] dataStream = new byte[formDataHeaderBuffer.Length + beginBuffer.Length + fileBuffer.Length + endBuffer.Length];
                formDataHeaderBuffer.CopyTo(dataStream, 0);
                beginBuffer.CopyTo(dataStream, formDataHeaderBuffer.Length);
                fileBuffer.CopyTo(dataStream, formDataHeaderBuffer.Length + begin.Length);
                endBuffer.CopyTo(dataStream, formDataHeaderBuffer.Length + begin.Length + fileBuffer.Length);
                var returnBuffer = webClient.UploadData(url, "POST", dataStream);
                Encoding encode = Encoding.UTF8;
                string resultJson = encode.GetString(returnBuffer);
                return resultJson;
            }

    调用的代码
    int timeout = 1000 * 60 * 5;
    String resultJson = RequestHelper.Post(requestUrl, "media", fileBuffer, fileName, timeout);//media是固定的字符串
    其中fileBuffer为文件的字节流,requestUrl按照接口的方式找接而成https://oapi.dingtalk.com/media/upload?access_token=ACCESS_TOKEN&type=TYPE。
    目前测出,type=file时是可行的,type=image时不知为何总是提示【系统繁忙】

    -------------------------

    回 6楼如意的帖子
    附上读取媒体文件的方法
    #region FetchMediaFile Function
            /// <summary>
            /// 获取媒体文件
            /// </summary>
            /// <param name="mediaId">媒体文件的id</param>
            /// <returns></returns>
            public static DDMediaFetchResult FetchMediaFile(string mediaId)
            {
                DDMediaFetchResult result = null;

                string apiurl = FormatApiUrlWithToken(Urls.media_get);
                apiurl = $"{apiurl}&{Keys.media_id}={mediaId}";
                WebClient webClient = new WebClient();
                var data = webClient.DownloadData(apiurl);
                int testHeaderMaxLength = 100;
                var testHeaderBuffer = new byte[(data.Length < testHeaderMaxLength ? data.Length : testHeaderMaxLength)];
                Array.Copy(data, 0, testHeaderBuffer, 0, testHeaderBuffer.Length);
                Encoding encoder = Encoding.UTF8;
                String testHeaderStr = encoder.GetString(testHeaderBuffer);
                if (testHeaderStr.StartsWith("--"))
                {//正常返回数据时,第一行数据为分界线,而分界线必然以"--"开始.
                    var tempArr = testHeaderStr.Split(new String[] { Environment.NewLine }, StringSplitOptions.None);
                    string boundary = tempArr[0] + Environment.NewLine;
                    int boundaryByteLength = encoder.GetBytes(boundary).Length;
                  byte[] destData = new byte[data.Length-boundaryByteLength];
                    Array.Copy(data, boundaryByteLength, destData, 0, destData.Length);
                    result = new DDMediaFetchResult();
                    result.ErrCode = DDErrCodeEnum.OK;
                    result.ErrMsg = "OK";
                    result.Data = destData;


                    const string Content_Length = "Content-Length";
                    if (webClient.ResponseHeaders == null || (!webClient.ResponseHeaders.AllKeys.Contains(Content_Length)))
                    {
                        result.FileLength = -1;
                    }

                    var lengthStr = webClient.ResponseHeaders[Content_Length];
                    int length = 0;
                    if (int.TryParse(lengthStr, out length))
                    {
                        result.FileLength = length;
                    }
                    else
                    {
                        result.FileLength = 0;
                    }

                    const string Content_Type = "Content-Type";
                    if (webClient.ResponseHeaders == null || (!webClient.ResponseHeaders.AllKeys.Contains(Content_Type)))
                    {
                        result.FileType = "unknown";
                    }
                    else
                    {
                        result.FileType = webClient.ResponseHeaders[Content_Type];
                    }
                }
                else
                {
                    string resultJson = encoder.GetString(data);
                    result = DDRequestAnalyzer.AnalyzeResult<DDMediaFetchResult>(resultJson);//将resultJson反序化为DDMediaFetchResult
                }
                return result;
            }
            #endregion

    /// <summary>
        /// 媒体文件获取结果
        /// </summary>
        public class DDMediaFetchResult
        {
        /// <summary>
            /// 错误码
            /// </summary>
        public int ErrCode{get;set;

            /// <summary>
            /// 错误消息
            /// </summary>
            public string ErrMsg { get; set; }}

            /// <summary>
            /// HTTP响应头
            /// </summary>
            public Dictionary<string, string> Header { get; set; }

            /// <summary>
            /// 获取的数据
            /// </summary>
            public byte[] Data { get; set; }

            /// <summary>
            /// 文件长度
            /// </summary>
            public int FileLength { get; set; }

            /// <summary>
            /// 文件类型
            /// </summary>
            public String FileType { get; set; }

        }
    2016-07-21 15:33:10
    赞同 展开评论 打赏
  • 上传文件不成功

    A:使用multipart/form-data请求上传文件,需要附加文件标示信息,参数名为media,java示例代码为

    HttpEntity requestEntity =MultipartEntityBuilder.create().addPart("media", new FileBody(file, ContentType.APPLICATION_OCTET_STREAM, file.getName())).build();

    可以参考这个常见问题的地址: https://open-doc.dingtalk.com/doc2/detail.htm?spm=a219a.7386797.0.0.rEbHnF&treeId=173&articleId=105077&docType=1
    2016-07-20 00:25:28
    赞同 展开评论 打赏
  • 旺旺:nectar2。
    楼主您好,

    为您将帖子移到钉钉的相关版块,希望能得到更快的回复。

    -------------------------

    回 2楼(钉钉-赤司) 的帖子
    您好,

    请帮忙看一下“地板”楼层的提问。谢谢。
    2016-07-19 19:18:15
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Architecting a Multi-Tenanted 立即下载
Architecting a Multi-Tenanted Platform 立即下载
低代码开发师(初级)实战教程 立即下载