DingTalk開發系列(七)媒體檔案的上傳與下載

來源:互聯網
上載者:User

官方提供的介面說明和樣本是基於java的,卻沒有對具體的header作出更詳細的說明,導致很難使用C#語言轉換,幾經測試,總算找到了個不是太完整的解決方案,代碼如下。

/// <summary>        ///POST檔案        /// </summary>        /// <param name="url"></param>        /// <param name="timeout"></param>        /// <param name="fileKeyName">比如DingTalk上傳媒體檔案使用的是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時不知為何總是提示【系統繁忙】,還請路過的大家們能夠提供解決方案。

在上傳成功後,需要再下載下來,下載時,由於成功和失敗的返回資料不一樣,所以需要先對前面的若干位元組進行了試探處理,之後再依據試探結果繼續處理,代碼如下

附上讀取媒體檔案的方法#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; }                    }
將收到的資料存成檔案即可,比如將前面上傳得到的mediaid傳入後,下載得到了下面的圖

附產生隨機串的方法

   #region GenerateRadomStr        /// <summary>        /// 產生隨機字串        /// </summary>        /// <param name="length">隨機串的長度</param>        /// <returns></returns>        public static string GenerateRadomStr(int length = 16)        {            string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";            string str = "";            Random rad = new Random();            for (int i = 0; i < length; i++)            {                str += chars.Substring(rad.Next(0, chars.Length - 1), 1);            }            return str;        }        #endregion

歡迎打描左側二維碼打賞。

轉載請註明出處。






相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.