1、Windows10环境下的Http20编程接口NOVEMBER 23, 2015 9:27 AMDemystifying HttpClient APIs in the Universal Windows PlatformByWindows Apps TeamSHARETWEETSHARESHARESKYPEAs a Universal Windows Platform (UWP) app developer, if you are trying to communicate over HTTP with a web service or any server endpoint, you hav
2、e multiple API choices. Two of the most used and recommended APIs for implementing the HTTP client role in a managed UWP app areSystem.Net.Http.HttpClientandWindows.Web.Http.HttpClient. These APIs should be preferred over older, discouraged APIs such as WebClient and HttpWebRequest (although a small
3、 subset of HttpWebRequest is available in UWP for backward compatibility).We have received several questions about the differences between these APIs, equivalent functionalities between the two, which one to use when, and so on. In this post, we will try to address these questions and help clarify t
4、he purpose of these two APIs.Brief OverviewThe System.Net.Http.HttpClient API was first introduced in .NET 4.5, and a variant was made available via a NuGet package down-level for .NET 4.0 and Windows Phone 8 Silverlight apps. The goal of this API was to provide a simpler, cleaner abstraction layer
5、and flexibility for implementing the HTTP client role, as compared to the older HttpWebRequest API. For example, it allows chaining custom handlers, by which developers could intercept each request or response, and implement custom logic. Up until Windows 8.1, this API had a fully managed .NET imple
6、mentation underneath. In Windows 10, the implementation of this API for UWP has been changed to layer it on top of Windows.Web.Http and the WinINet HTTP stack of Windows.On the other hand, the Windows.Web.Http.HttpClient API, was first introduced in Windows 8.1 and was available on Windows Phone 8.1
7、 as well. The primary motivation behind creating this API was to consolidate the disparate HTTP APIs available for different Windows app languages (C#, VB, C+, JavaScript) into a single one that supports all the features from each of those APIs. Most of the basic API design was derived from that of
8、System.Net.Http and the implementation is based on the WinINet HTTP stack of Windows.When using these APIs in a Windows Store app, the supported OS versions and programming languages are as follows:APIOS VersionsSupported LanguagesSystem.Net.Http.HttpClientWindows, Windows Phone 8 onwards.NET langua
9、ges onlyWindows.Web.Http.HttpClientWindows, Windows Phone 8.1 onwardsAll Windows Store app languagesWhich one should I use?Since both of these APIs are available in UWP, the biggest question for HTTP developers is which one to use in their app. The answer is that it depends on a couple of factors:1.
10、 Do you need to integrate with native UI for collecting user credentials, control HTTP cache read and write behavior; or pass in a specific SSL client certificate for authentication?If yes then use Windows.Web.Http.HttpClient. At the time of this writing, the Windows.Web.Http API provides greater co
11、ntrol over HTTP settings in UWP than the System.Net.Http API. In future versions, the System.Net.Http API may also be enhanced to support these features on UWP.2. Do you intend to write cross-platform .NET code (across UWP/ASP.NET 5/iOS and Android)?If yes then use System.Net.Http API. This allows y
12、ou to write code that you can re-use on other .NET platforms such as ASP.NET 5 and .NET Framework desktop applications. Thanks toXamarin, this API is also supported on iOS and Android, so you can reuse your code on these platforms as well.Object ModelNow that we understand the motivation behind crea
13、ting these two similar APIs and the rationale for choosing between the two, lets look closer at the object model for each of these.System.Net.HttpThe topmost abstraction layer is theHttpClientobject, which represents the client entity in the client-server model of the HTTP protocol. This client can
14、issue multiple requests (represented byHttpRequestMessage) to the server and receive the corresponding responses (represented byHttpResponseMessage). The entity body and content headers of each HTTP request or response is represented by theHttpContentbase class, and derived classes such as StreamCon
15、tent, MultipartContent and StringContent. They provide different representations of the HTTP entity body. Each of these classes provide a set of ReadAs* methods to read out the entity body of a request or response as a string, byte array or a stream.Each HttpClient object has a handler object undern
16、eath that represents all the HTTP-related settings of that client. Conceptually, you can think of the handler as representing the HTTP stack underneath the client. It is responsible for sending the clients HTTP requests to the server and conveying the response back to the client.The default handler
17、class used in the System.Net.Http API isHttpClientHandler. When you create a new instance of an HttpClient objectfor example, call new HttpClient()an HttpClientHandler object is automatically created for you with the default HTTP stack settings. If you want to modify any of the default settings such
18、 as caching behavior, automatic compression, credentials or proxy, you can create your own instance of an HttpClientHandler directly, modify its properties and then pass it into the constructor of HttpClient, as follows:123HttpClientHandler myHandler = new HttpClientHandler();myHandler.AllowAutoRedi
19、rect = false;HttpClient myClient = new HttpClient(myHandler);Chaining of HandlersOne of the key advantages of the System.Net.Http.HttpClient API design is the ability to insert custom handlers and create a chain of handler objects underneath an HttpClient object. For example, lets say you are buildi
20、ng an app that queries a web service for some data. You have custom logic to handle HTTP 4xx (client error) and 5xx (server error) responses from the server and want to take specific retry steps, such as trying a different endpoint or adding user credentials. You would ideally want to separate this
21、HTTP-related work from the rest of your business logic which just cares about the data returned from the web service.This can be achieved by creating a new handler class that derives from theDelegatingHandlerclass (e.g. CustomHandler1), then create a new instance of it and pass that in to the HttpCl
22、ient constructor. The InnerHandler property of the DelegatingHandler class is used to specify the next handler in the chain for example, you could add another custom handler (e.g. CustomHandler2) to the chain. For the last handler, you can set the inner handler to an HttpClientHandler instance this
23、will pass the request on to the HTTP stack of the OS. Heres how this looks conceptually:And here is the sample code to achieve this:12345678910111213141516171819202122232425262728293031323334353637383940public class CustomHandler1 : DelegatingHandler/ Constructors and other code here.protected async
24、 override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)/ Process the HttpRequestMessage object here.Debug.WriteLine(Processing request in Custom Handler 1);/ Once processing is done, call DelegatingHandler.SendAsync to pass it on the / inner handler.HttpResponseMess
25、age response = await base.SendAsync(request, cancellationToken);/ Process the incoming HttpResponseMessage object here.Debug.WriteLine(Processing response in Custom Handler 1);return response;public class CustomHandler2 : DelegatingHandler/ Similar code as CustomHandler1.public class Foopublic void
26、CreateHttpClientWithChain()HttpClientHandler systemHandler = new HttpClientHandler();CustomHandler1 myHandler1 = new CustomHandler1();CustomHandler2 myHandler2 = new CustomHandler2();/ Chain the handlers together.myHandler1.InnerHandler = myHandler2;myHandler2.InnerHandler = systemHandler;/ Create t
27、he client object with the topmost handler in the chain.HttpClient myClient = new HttpClient(myHandler1);Notes:1. If you intend to send the request to a remote server endpoint, the last Handler in a chain is typically HttpClientHandler, which actually sends the request out on the wire and receive the
28、 response from the HTTP stack of the OS. Alternatively, you could use a mock handler that pretends to be the server and returns fabricated responses.2. Adding processing logic in the handler before passing the request to the inner handler or the response to the upper handler can lead to performance
29、loss. It is best to avoid expensive synchronous operations in this scenario.For more details on the concept of chaining Handlers, seethis postby Henrik Nielsen (Note that it refers to the ASP.NET Web API version of the API, which is slightly different from the .NET framework one discussed here. The
30、concept of chaining handlers is common though.)Windows.Web.HttpThe object model for the Windows.Web.Http API is very similar to that of the System.Net.Http version described above it also has the concept of a client entity, a handler (called “filter” in this namespace) and the option of inserting cu
31、stom logic between the client and the system-default filter.Most of the types are direct analogs of the types in the System.Net.Http object model, as follows:HTTP client role aspectSystem.Net.Http typeCorresponding Windows.Web.Http typeClient entityHttpClientHttpClientHTTP requestHttpRequestMessageHttpRequestMessageHTTP responseHttpResponseMessageHttpResponseMessageEntity body of an HTTP request or responseHttpContentIHttpContentRepresent
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1