zoukankan      html  css  js  c++  java
  • HttpClient 详解一《C#高级编程(第9版)》

    1.异步调用 Web 服务

    static void Main(string[] args)
        {
            Console.WriteLine("In main before call to GetData!");
            GetData();
            Console.WriteLine("Back in main after call to GetData!");
            Console.ReadKey();
        }
    
        private static async void GetData()
        {
            HttpClient httpClient = new HttpClient();
            HttpResponseMessage response = null;
            response = await httpClient.GetAsync("http://services.odata.org/Northwind/Northwind.svc/Regions");
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine("Response Status Code and Reason Phrase: " + response.StatusCode + " " + response.ReasonPhrase);
                string responseBodyAsText = response.Content.ReadAsStringAsync().Result;
                Console.WriteLine("Received payload of " + responseBodyAsText.Length + " characters");
                //Console.WriteLine(responseBodyAsText);
            }
        }

    结果
    来看看下面方法解释:
    方法

    因为 HttpClient 使用 GetAsync 方法调用,且使用了 await,所以 Main 方法输出到屏幕的消息先显示,而 GetData 调用中的数据后显示。

    对 GetAsync 返回一个 HttpResponseMessage 对象。表示包含的标题、状态和内容的响应。检查响应的 IsSuccessStatusCode 属性,可以确定请求是否成功。

    2.标题

    HttpClient 的 DefaultRequestHeaders 属性允许设置或改变标题。使用 Add 可以给集合添加标题。下面意义相同。

    //httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    标题和标题值会与这个 HttpClient 实例发送的每个请求一起发送。

    下面的例子说明了如何在响应和请求中遍历标题。

        static void Main(string[] args)
        {
            GetData();
            Console.ReadKey();
        }
    
        private static void GetData()
        {
            HttpClient httpClient = new HttpClient();
            HttpResponseMessage response = null;
            httpClient.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
            Console.WriteLine("Request Headers:");
            //请求的标题
            EnumerateHeaders(httpClient.DefaultRequestHeaders);
            Console.WriteLine();
    
            response = httpClient.GetAsync("http://services.odata.org/Northwind/Northwind.svc/Regions").Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine("Response Headers:");
                EnumerateHeaders(response.Headers);          //结尾的标题
            }
        }
    • HttpHeaders 是 HttpRequestHeaders 和 HttpResponseHeaders 的基类。
    • HttpHeaders对象定义的为 KeyValuePair<string, IEnumerable<string>>。这表示每个标题在集合中都可以有多个值。因此要改变标题中的值,就需要先删除原来的值,添加新值。
        private static void EnumerateHeaders(HttpHeaders headers)
        {
            foreach (var header in headers)
            {
                var value = ""; 
                foreach (var val in header.Value)
                {
                    value = val + " ";
                }
                Console.WriteLine("Header: " + header.Key + " Value: " + value);
            }
        }

    因为标题值可以有多个,标题值部分也必须迭代,所以在循环内部还有一个循环,来枚举所有找到的值。

    效果

    3.HttpContent

    响应中的 Content 属性返回一个 HttpContent 对象。例子中使用 ReadAsStringAsync 返回内容的字符串表示。顾名思义,这是一个异步调用,但这个例子没使用异步调用功能。调用 Result 会阻塞该调用,直到 ReadAsStringAsync 方法执行完毕。

        var client = new HttpClient();
        //GetAsync 方法也接受一个 CancellationToken
        HttpResponseMessage response = await client.GetAsync("http://www.baidu.com");
        response.EnsureSuccessStatusCode();
        string html = await response.Content.ReadAsStringAsync();
        Console.WriteLine(html);

    其他从 HttpContent 对象获取数据的方法有 ReadAsByteArrayAsync(返回数据的字节数组)和 ReadAsStreamAsync(返回一个流)。也可以使用 LoadIntoBufferAsync 把内容加载到内存缓存中。

    Headers 属性返回 HttpCotentHeaders 对象。它工作方式与前面例子的请求和响应标题相同。

    4.HttpMessageHandler

    • 作为 HttpClient 构造函数的参数,就可以定制请求。
    • 默认使用 WebRequestHandler 对象。
    • 有许多属性可以设置 ClientCertificates、Pipelining、CachePolity、ImpersonationLevel 等。
        class Program
        {
    
            static void Main(string[] args)
            {
                GetData();
                Console.ReadKey();
            }
    
            private static void GetData()
            {
                HttpClient httpClient = new HttpClient(new MessageHandler("error"));
                HttpResponseMessage response = null;
                Console.WriteLine();
                response = httpClient.GetAsync("http://services.odata.org/Northwind/Northwind.svc/Regions").Result;
                Console.WriteLine(response.StatusCode);
            }
        }
    
    
        public class MessageHandler : HttpClientHandler  //HttpClientHandler 继承自  HttpMessageHandler
        {
            string displayMessage = "";
    
            public MessageHandler(string message)
            {
                displayMessage = message;
            }
    
            protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
            {
                Console.WriteLine("In DisplayMessageHandler " + displayMessage);
                if (displayMessage == "error")
                {
                    var response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);  //创建要返回的响应 把状态设置为  BadRequest
                    var tsc = new TaskCompletionSource<HttpResponseMessage>();
                    tsc.SetResult(response);       //注意响应在 HttpResponseMessage 任务中 SetResult 方法设置
                    return tsc.Task;
                }
                return base.SendAsync(request, cancellationToken);
            }
        }

    检查 displayMessage ,是否为“error”。如果是,就创建要返回的响应,把状态设为 BadRequest。接下来只创建了要返回的 Task。注意响应在 HttpResponseMessage 任务中通过 SetResult 方法设置。

    添加定制处理器程序有很多理由。设置处理程序管道,是为添加多个处理程序。除了默认的处理程序外,还有 DelegatingHandler,它执行一些代码,再把调用委托给内部或下一个处理程序。 HttpClientHandler 是最后一个处理程序,它把请求发送到地址。
    每个添加的 DelegatingHandler都调用下一个或内部的处理程序,最后一个是基于 HttpClientHandler处理程序。

    处理程序管道

    http://www.cnblogs.com/tangge/p/7082871.html

  • 相关阅读:
    hdu 6010 Daylight Saving Time
    hdu 5999 The Third Cup is Free
    2011 USP Try-outs F. Auction of Services
    1449 砝码称重
    hdu 6205 card card card
    hdu 6201 transaction transaction transaction
    Codeforces 828D
    Codeforces Round #434 D
    zoj
    Codeforces Round #434 C
  • 原文地址:https://www.cnblogs.com/cmblogs/p/9155968.html
Copyright © 2011-2022 走看看