zoukankan      html  css  js  c++  java
  • httpclient

    在此讲一下httpclient类的使用,在之前《网络数据请求request》中讲过WebClient和HttpWebRequest ,在此讲一下httpclient,同时对《网络数据请求request》中的一些问题进行优化。

    httpclient需要.net4.5以上,在System.Net.Http;命名空间下。httpclient通过关键字await实现异步操作,方便简洁而且效率高,缺点是需要较高的.net版本。对于get和post方法分别采用await以及task的continewith进行异步操作;

    1)get

            /// <summary>
            /// await 异步请求
            /// get
            /// </summary>
            static async void HttpClientGetAsync()
            {
                HttpClient httpClient = new HttpClient();
                HttpResponseMessage response = await httpClient.GetAsync("http://www.sojson.com/open/api/weather/json.shtml?city=闵行区");
                response.EnsureSuccessStatusCode();
                string result = await response.Content.ReadAsStringAsync();
                Console.WriteLine(result);
            }
            /// <summary>
            /// task  请求
            /// get
            /// </summary>
            static void HttpClientGet()
            {
                HttpClient httpClient = new HttpClient();
               
                httpClient.GetAsync("http://www.sojson.com/open/api/weather/json.shtml?city=闵行区").ContinueWith(
                    (getTask) =>
                    {
                        HttpResponseMessage response = getTask.Result;                   
                       response.EnsureSuccessStatusCode();                   
                       response.Content.ReadAsStringAsync().ContinueWith(
                            (readTask) => Console.WriteLine(readTask.Result));
                    });      
            }

    1)post

    post对应于不同的contentType对应四种提交数据的方法,具体可参见《网络数据请求request》,在此不在赘述,不管是何种类型的请求,httpclient的请求主体可以通过表单(FormUrlEncodedContent或者MultipartFormDataContent等继承自httpcontent类)进行进行提交,而不必自己构造请求主体。

    (一)contentType=application/x-www-form-urlencoded

           /// <summary>
            /// post await
            /// 
            /// </summary>
            static async void HttpClientPostAsync()
            {
                HttpClient httpClient = new HttpClient();
                httpClient.DefaultRequestHeaders.Add("Method", "Post");
                httpClient.DefaultRequestHeaders.Add("KeepAlive", "false");// HTTP KeepAlive设为false,防止HTTP连接保持
    
                HttpContent postContent = new FormUrlEncodedContent(new Dictionary<string, string>()
               {
                  {"api_key", "3333333333333333333333333333333"},
                  {"api_secret", "33333333333333333333333333333333333333"},
                  {"image_url","https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1508759666809&di=b3748df04c5e54d18fe52ee413f72f37&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F562c11dfa9ec8a1389c45414fd03918fa1ecc06c.jpg" }
                });
    
                HttpResponseMessage response = await httpClient.PostAsync("https://api-cn.faceplusplus.com/facepp/v3/detect", postContent);
                response.EnsureSuccessStatusCode();
                string result = await response.Content.ReadAsStringAsync();
                Console.WriteLine(result);
            }
            /// <summary>
            /// post task请求
            /// </summary>
            static void HttpClientPost()
            {
                HttpClient httpClient = new HttpClient();         
                httpClient.DefaultRequestHeaders.Add("Method", "Post");
                httpClient.DefaultRequestHeaders.Add("KeepAlive", "false");// HTTP KeepAlive设为false,防止HTTP连接保持
    
                // post form
                HttpContent postContent = new FormUrlEncodedContent(new Dictionary<string, string>()
               {
                  {"api_key", "3333333333333333333333"},
                  {"api_secret", "333333333333333333333333333333"},
                  {"image_url","https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1508759666809&di=b3748df04c5e54d18fe52ee413f72f37&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F562c11dfa9ec8a1389c45414fd03918fa1ecc06c.jpg" }
               });
    
                httpClient
                   .PostAsync("https://api-cn.faceplusplus.com/facepp/v3/detect", postContent)
                   .ContinueWith(
                   (postTask) =>
                   {
                       HttpResponseMessage response = postTask.Result;                
                       response.EnsureSuccessStatusCode();                  
                       response.Content.ReadAsStringAsync().ContinueWith(
                           (readTask) => Console.WriteLine(readTask.Result));                
                   });
            }

    (一)multipart/form-data

    采用此种方式是为了提交文件,请求主体通过表单类进行提交,不必自己构造主体,节省很大工作量。提交数据主体跟《网络数据请求request》中的一样,不过提交数据表单头如Content-disposition: form-data; name="key2" 需要在提交内容的header中添加,代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Net.Http;
    using System.IO;
    using System.Net.Http.Headers;
    
    namespace HttpClientPostFile
    {
        class RequestHttpClient
        {
            public class FilePost  //image
            {
                public string fullPath;
                public string imageName;
                public string contentType = "application/octet-stream";
    
                public FilePost(string path)
                {
                    fullPath = path;
                    imageName = Path.GetFileName(path);
                }
            }
    
            private static HttpContent GetMultipartForm(Dictionary<string,object> postForm)
            {
                string boundary = string.Format("--{0}", Guid.NewGuid());
                MultipartFormDataContent httpContent = new MultipartFormDataContent(boundary);
    
                foreach(KeyValuePair<string,object> pair in postForm)
                {
                    if(pair.Value is FilePost)
                    {                    
                        FilePost file = (FilePost)pair.Value;         
                        byte[] b = File.ReadAllBytes(file.fullPath);
                        ByteArrayContent byteArrContent = new ByteArrayContent(File.ReadAllBytes(file.fullPath));
                        byteArrContent.Headers.Add("Content-Type", "application/octet-stream");
                        byteArrContent.Headers.Add("Content-Disposition",string.Format("form-data; name={0}; filename={1}",pair.Key,file.imageName));
                        httpContent.Add(byteArrContent);
                    }
                    else
                    {
                        string value = (string)pair.Value;
                        StringContent stringContent = new StringContent(value);
                        stringContent.Headers.Add("Content-Disposition",string.Format("form-data; name={0}",pair.Key));
                        httpContent.Add(stringContent);
                    }
                }
                return httpContent;
            }
    
            private static async void HttpClientPostFileAsync(HttpContent httpContent,string url)
            {
                string result = "";
                HttpClient httpClient = new HttpClient();
                httpClient.DefaultRequestHeaders.Add("Method", "Post");
                httpClient.DefaultRequestHeaders.Add("KeepAlive", "false");// HTTP KeepAlive设为false,防止HTTP连接保持
    
                try
                {
                    HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
                    response.EnsureSuccessStatusCode();
                    result = await response.Content.ReadAsStringAsync();
                }
                catch(HttpRequestException ex)
                {
                    result = ex.Message;
                }
    
                Console.WriteLine(result);
            }
    
            public static void HttpRequestByPostfileAsync(Dictionary<string,object> postForm,string url)
            {
                HttpClientPostFileAsync(GetMultipartForm(postForm), url);
            }
        }
    }

    调用代码如下所示:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    
    
    namespace HttpClientPostFile
    {
        class Program
        {
            static void Main(string[] args)
            {
                string path = @"D:	estimage1.jpg";
                string url = "https://api-cn.faceplusplus.com/facepp/v3/detect";
                RequestHttpClient.FilePost filePost = new RequestHttpClient.FilePost(path);
    
                Dictionary<string, object> postParameter = new Dictionary<string, object>();
                postParameter.Add("api_key", "3333333333333333");
                postParameter.Add("api_secret", "3333333333333333333333333");
                postParameter.Add("image_file", filePost);
                //postParameter.Add("image_url", "http://imgtu.5011.net/uploads/content/20170328/7150651490664042.jpg");
    
                RequestHttpClient.HttpRequestByPostfileAsync(postParameter, url);
                Console.ReadKey();
            }
        }
    }

    PS:1)主程序中除其他参数外,提交的文件只需要在postParameter添加对应的提交参数与文件路径即可

          2)《网络数据请求request》中为了体现text文件与image文件的不同,采取不同的获取文件数据的方式(image通过Bitmap 类获取数据),本例中都采用一般文件获取文件信息

          3)代码中api_key、api_secret分别为face++的key和secret,涉及到账号问题已经抹去,代码测试可以去申请一个账号,很容易。

          4)代码亲测有效,但在异常处理方面未做周全考虑,使用者可以自己根据需求在做相关处理

  • 相关阅读:
    BZOJ 1014 火星人prefix
    BZOJ 1013 球形空间产生器
    BZOJ 1012 最大数
    BZOJ 1011 遥远的行星
    BZOJ 1010 玩具装箱
    BZOJ 1009 GT考试
    BZOJ 1008 越狱
    BZOJ 1007 水平可见直线
    BZOJ 1006 神奇的国度
    Luogu 1450 [HAOI2008]硬币购物
  • 原文地址:https://www.cnblogs.com/llstart-new0201/p/7777890.html
Copyright © 2011-2022 走看看