zoukankan      html  css  js  c++  java
  • 新浪微博SDK开发(2):上传图片的技术难点

    在微博模块中,有一个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属性返回服务器回应的消息正文。

    这样,上传图片的问题就解决了。

  • 相关阅读:
    0309. Best Time to Buy and Sell Stock with Cooldown (M)
    0621. Task Scheduler (M)
    0106. Construct Binary Tree from Inorder and Postorder Traversal (M)
    0258. Add Digits (E)
    0154. Find Minimum in Rotated Sorted Array II (H)
    0797. All Paths From Source to Target (M)
    0260. Single Number III (M)
    0072. Edit Distance (H)
    0103. Binary Tree Zigzag Level Order Traversal (M)
    0312. Burst Balloons (H)
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/3818337.html
Copyright © 2011-2022 走看看