新浪微博SDK開發(2):上傳圖片的技術痛點

來源:互聯網
上載者:User

標籤:style   blog   http   color   使用   strong   

在微博模組中,有一個API是可以發錶帶一張圖片的微博的,當然提交方式是POST。在封裝的時候,可能會遇到一個痛點——如何上傳圖片?

要POST微博的同時帶有圖片,POST的內容必須為MultiPart form data格式的內容,這個呢,我用到.NET 45中新增的一個相當強大的HttpClient類,位於System.Net.Http命名空間下。這個類的好處在於,它把許多HTTP操作都封裝了,讓我們使用起來不至於過於痛苦。

源碼下載:http://vdisk.weibo.com/s/z7iFc2gCCwC1b

無論是GET請求還是POST請求,HttpClient類都允許我們發送一個HttpContent對象,它封裝了HTTP內容資料,當然它是一個抽象類別,我們用的是它的衍生類別,請看:

 

 StringContent類是把一個字串發送到伺服器,StreamContent類表示資料內容以流的形式收發,FormUrlEncodedContent類封裝的資料,說簡單一點就是類比我們在web頁上form元素中填寫的內容。

而既有文本又有圖片檔案的微博,應該使用MultipartFormDataContent來封裝,即包含多個段的資料,正因其有多個 Content-Disposition段,我們需要弄一個字串作為分隔字元,在這裡,就是把微博本文和圖片檔案的資料分隔開來,這個字串常見的形式如“---------------------------a6ecd24f3a2b3cc5”。

於是,我在SDK中專為POST這種多段資料的HTTP內容寫了一個SendRequestWithMultipartFormDataAsync,都是async方法,可以非同步等待,這是新特性,有些人不太瞭解它,其實當你瞭解後,你會發現await非同步等待其實很環保,也節省不少代碼。

        internal static async Task<TResult> SendRequestWithMultipartFormDataAsync<TResult>(string relateUrl, IDictionary<string, object> parms, string filename)        {            Uri reqUri = new Uri(API_BASE_RUI);            reqUri = new Uri(reqUri, relateUrl);            TResult result = default(TResult);            using (HttpClient client = new HttpClient())            {                string b = "---------------------" + DateTime.Now.Ticks.ToString("x");                MultipartFormDataContent formData = new MultipartFormDataContent(b);                foreach (var pair in parms)                {                    string str = pair.Value as string;                    if (str != null)                    {                        StringContent stringContent = new StringContent(pair.Value as string);                        formData.Add(stringContent, pair.Key);                    }                    Stream stream = pair.Value as Stream;                    if (stream != null)                    {                        StreamContent streamContent = new StreamContent(stream);                        formData.Add(streamContent, pair.Key, filename);                    }                }                var response = await client.PostAsync(reqUri, formData);                if (response.IsSuccessStatusCode)                {                    using (Stream backstream = await response.Content.ReadAsStreamAsync())                    {                        result = JsonSerializeHelper.ReadDataFromJson<TResult>(backstream);                    }                }                else                {                    ErrorData err = null;                    using (Stream errstream = await response.Content.ReadAsStreamAsync())                    {                        err = JsonSerializeHelper.ReadDataFromJson<ErrorData>(errstream);                    }                    throw new WeiboException(err);                }            }            return result;        }

用於分隔內容的字串,我是通過把DateTime對象中的Ticks這個數值轉為十六進位字串來實現的,也就是代碼中的b變數。

1、new一個MultipartFormDataContent對象。

2、微博本文是字串,所以用StringContent來封裝,然後調用MultipartFormDataContent對象的Add方法加進去。

3、對於圖片,我們可以使用流StreamContent,但要注意一個很關鍵的要素,就是在Add到multipart form data 內容中的時候一定要指定檔案名稱。即調用以下重載:

public void Add(HttpContent content, string name, string fileName);

也就是必須為filename參數給予一個檔案名稱,相對路徑,絕對路徑都無所謂,或者乾脆一個檔案名稱(如abc.jpg)都行。就是不能缺了這個參數,否則會上傳失敗。
將內容添加完畢後,就可以直接調用PostAsync方法向伺服器POST資料了,完成後返回HttpResponseMessage類型的執行個體,它封裝了伺服器回應的各種訊息,可通過IsSuccessStatusCode屬性判斷伺服器是否返回正確的代碼(OK,200)。Content屬性返回伺服器回應的訊息本文。

這樣,上傳圖片的問題就解決了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.