HttpClient 詳解一《C#高級編程(第9版)》

1.異步調(diào)用 Web 服務(wù)

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);
        }
    }
結(jié)果

來看看下面方法解釋:


方法

因為 HttpClient 使用 GetAsync 方法調(diào)用荤牍,且使用了 await,所以 Main 方法輸出到屏幕的消息先顯示棺禾,而 GetData 調(diào)用中的數(shù)據(jù)后顯示。

對 GetAsync 返回一個 HttpResponseMessage 對象。表示包含的標(biāo)題、狀態(tài)和內(nèi)容的響應(yīng)咙冗。檢查響應(yīng)的 IsSuccessStatusCode 屬性,可以確定請求是否成功漂彤。

2.標(biāo)題

HttpClient 的 DefaultRequestHeaders 屬性允許設(shè)置或改變標(biāo)題雾消。使用 Add 可以給集合添加標(biāo)題。下面意義相同挫望。

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

標(biāo)題和標(biāo)題值會與這個 HttpClient 實例發(fā)送的每個請求一起發(fā)送仪或。

下面的例子說明了如何在響應(yīng)和請求中遍歷標(biāo)題。

    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:");
        //請求的標(biāo)題
        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);          //結(jié)尾的標(biāo)題
        }
    }
  • HttpHeadersHttpRequestHeadersHttpResponseHeaders 的基類士骤。
  • HttpHeaders對象定義的為 KeyValuePair<string, IEnumerable<string>>。這表示每個標(biāo)題在集合中都可以有多個值蕾域。因此要改變標(biāo)題中的值拷肌,就需要先刪除原來的值,添加新值旨巷。
    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);
        }
    }

因為標(biāo)題值可以有多個巨缘,標(biāo)題值部分也必須迭代,所以在循環(huán)內(nèi)部還有一個循環(huán)采呐,來枚舉所有找到的值若锁。

效果

3.HttpContent

響應(yīng)中的 Content 屬性返回一個 HttpContent 對象。例子中使用 ReadAsStringAsync 返回內(nèi)容的字符串表示斧吐。顧名思義又固,這是一個異步調(diào)用仲器,但這個例子沒使用異步調(diào)用功能。調(diào)用 Result 會阻塞該調(diào)用仰冠,直到 ReadAsStringAsync 方法執(zhí)行完畢乏冀。

    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 對象獲取數(shù)據(jù)的方法有 ReadAsByteArrayAsync(返回數(shù)據(jù)的字節(jié)數(shù)組)和 ReadAsStreamAsync(返回一個流)。也可以使用 LoadIntoBufferAsync 把內(nèi)容加載到內(nèi)存緩存中洋只。

Headers 屬性返回 HttpCotentHeaders 對象辆沦。它工作方式與前面例子的請求和響應(yīng)標(biāo)題相同。

4.HttpMessageHandler

  • 作為 HttpClient 構(gòu)造函數(shù)的參數(shù)识虚,就可以定制請求肢扯。
  • 默認(rèn)使用 WebRequestHandler 對象。
  • 有許多屬性可以設(shè)置 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);  //創(chuàng)建要返回的響應(yīng) 把狀態(tài)設(shè)置為  BadRequest
                var tsc = new TaskCompletionSource<HttpResponseMessage>();
                tsc.SetResult(response);       //注意響應(yīng)在 HttpResponseMessage 任務(wù)中 SetResult 方法設(shè)置
                return tsc.Task;
            }
            return base.SendAsync(request, cancellationToken);
        }
    }

檢查 displayMessage 蛛株,是否為“error”。如果是育拨,就創(chuàng)建要返回的響應(yīng)谨履,把狀態(tài)設(shè)為 BadRequest。接下來只創(chuàng)建了要返回的 Task熬丧。注意響應(yīng)在 HttpResponseMessage 任務(wù)中通過 SetResult 方法設(shè)置笋粟。

添加定制處理器程序有很多理由。設(shè)置處理程序管道析蝴,是為添加多個處理程序害捕。除了默認(rèn)的處理程序外,還有 DelegatingHandler闷畸,它執(zhí)行一些代碼尝盼,再把調(diào)用委托給內(nèi)部或下一個處理程序。 HttpClientHandler 是最后一個處理程序佑菩,它把請求發(fā)送到地址盾沫。
每個添加的 DelegatingHandler都調(diào)用下一個或內(nèi)部的處理程序谅年,最后一個是基于 HttpClientHandler處理程序摩桶。

處理程序管道
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市甥绿,隨后出現(xiàn)的幾起案子绞幌,更是在濱河造成了極大的恐慌蕾哟,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異谭确,居然都是意外死亡帘营,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門琼富,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仪吧,“玉大人,你說我怎么就攤上這事鞠眉∈硎螅” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵械蹋,是天一觀的道長出皇。 經(jīng)常有香客問我,道長哗戈,這世上最難降的妖魔是什么郊艘? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮唯咬,結(jié)果婚禮上纱注,老公的妹妹穿的比我還像新娘。我一直安慰自己胆胰,他們只是感情好狞贱,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜀涨,像睡著了一般瞎嬉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上厚柳,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天氧枣,我揣著相機(jī)與錄音,去河邊找鬼别垮。 笑死便监,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碳想。 我是一名探鬼主播烧董,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼移袍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起老充,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤葡盗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體觅够,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡胶背,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了喘先。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钳吟。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖窘拯,靈堂內(nèi)的尸體忽然破棺而出红且,到底是詐尸還是另有隱情,我是刑警寧澤涤姊,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布暇番,位于F島的核電站,受9級特大地震影響思喊,放射性物質(zhì)發(fā)生泄漏壁酬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一恨课、第九天 我趴在偏房一處隱蔽的房頂上張望舆乔。 院中可真熱鬧,春花似錦剂公、人聲如沸希俩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斜纪。三九已至,卻和暖如春文兑,著一層夾襖步出監(jiān)牢的瞬間盒刚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工绿贞, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留因块,地道東北人。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓籍铁,卻偏偏與公主長得像涡上,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拒名,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理吩愧,服務(wù)發(fā)現(xiàn),斷路器增显,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 10,970評論 6 13
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法雁佳,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法糖权,異常的語法堵腹,線程的語...
    子非魚_t_閱讀 31,632評論 18 399
  • 每天一個小時喝茶聊事的時間已經(jīng)成為一種習(xí)慣。 今天我煮了白茶星澳。 今天的分享與白茶有關(guān)疚顷,意境在煮茶時。 從開始接觸白...
    So大江哥閱讀 497評論 0 0
  • (by孤坐未央) 我在千里冰封的山上坐著 一揮手碰倒了南方的月光 于是你那里的天空熠熠發(fā)亮 我曾告訴你 我擁有一座...