Calling a Web API From a .NET Client (C#)
2013-08-09 10:12
357 查看
This tutorial shows how to call a web API from a console application, using
HttpClient.
In this tutorial, we will consume the
"ProductStore" API, described in
Creating a Web API that Supports CRUD Operations.
File menu, select New and then Project.
In the Templates pane, select Installed Templates and expand the
Visual C# node. Under Visual C#, select
Windows. In the list of project templates, select Console Application. Name the project and click
OK.
![](http://i1.asp.net/media/3699352/httpclient04.png?cdn_id=2013-07-15-001)
Start Visual Studio.
From the Tools menu, select Extensions and Updates.
In the Extensions and Updates dialog, select Online.
If you don't see "NuGet Package Manager", type "nuget package manager" in the search box.
Select the NuGet Package Manager and click Download.
After the download completes, you will be prompted to install.
After the installation completes, you might be prompted to restart Visual Studio.
![](http://i3.asp.net/media/3202344/webapi_selfhost03.png?cdn_id=2013-07-15-001)
From the Tools menu, select Library Package Manager.
Note: If do you not see this menu item, make sure that NuGet Package Manager installed correctly.
Select Manage NuGet Packages for Solution...
In the Manage NugGet Packages dialog, select Online.
In the search box, type "Microsoft.AspNet.WebApi.Client".
Select the package named "Microsoft ASP.NET Web API Client Libraries".
Click Install.
After the package installs, click Close to close the dialog.
![](http://i2.asp.net/media/3672696/httpclient02.png?cdn_id=2013-07-15-001)
This class creates a data object that HttpClient will write into the HTTP request body and read from the HTTP response body.
This code sets the base URI to "http://localhost:9000/", and sets the Accept header to "application/json", which tells the server to send data in JSON format.
The GetAsync method sends an HTTP GET request. As the name implies,
GetAsyc is asynchronous. It returns immediately, without waiting for a response from the server. The return value is a
Task object that represents the asynchronous operation. When the operation completes, the
Task.Result property contains the HTTP response.
It is important to understand that taking the Result property blocks your application thread until the request completes (or times out). Blocking in a console application is OK, but you should never do this on the UI thread of a Windows
application, because it blocks the UI from responding to user input. In the next part of this tutorial, we'll see how to write non-blocking calls.
If the HTTP response indicates success, the response body contains a list of products in JSON format. To parse the list, call
ReadAsAsync. This method reads the response body and tries to deserialize it to a specified CLR type. This method is also asynchronous, because the body can be arbitrarily large. Again, taking the
Result property blocks the thread.
Example HTTP session:
Getting a product by ID is similar:
support JSON, XML, and Form-url-encoded data. (For more information about media-type formatters, see
Formats and Model Binding.)
You can also explicitly specify the media-types formatters to use. This is useful if you have a custom media-type formatter.
PostAsJsonAsync is an extension method defined in System.Net.Http.HttpClientExtensions. It is equivalent to the following:
For XML format, use the PostAsXmlAsync method.
Example HTTP session:
By default, the JSON formatter sets the content-type to "application/json". You can also specify the media type explicitly. For example, suppose that "application/vnd.example.product" is your media type for
The PutAsJsonAsync method works like PostAsJsonAsync, except it sends a PUT request instead of POST.
Like GET, a DELETE request does not have a request body, so you don't need to specify JSON or XML format.
StatusCode property on the response contains the status code. Also, the
IsSuccessStatusCode property is true if the status is a success code (status codes in the range 200-299).
The previous examples used this pattern:
If you prefer to treat error codes as exceptions, call the EnsureSuccessStatusCode method. This method throws an exception if the response status is not a success code.
HttpClient can throw exceptions for other reasons, of course — for example, if the request times out.
WebRequestHandler instance, set properties on it, and pass it to the
HttpClient constructor:
WebRequestHandler derives from HttpMessageHandler. You can also plug in custom message handlers by deriving from
HttpMessageHandler. For more information, see
HTTP Message Handlers.
HttpClient without blocking, see
Calling a Web API From a WPF Application
参考资料
http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client
HttpClient.
In this tutorial, we will consume the
"ProductStore" API, described in
Creating a Web API that Supports CRUD Operations.
Create the Console Application
Start Visual Studio and select New Project from the Start page. Or, from theFile menu, select New and then Project.
In the Templates pane, select Installed Templates and expand the
Visual C# node. Under Visual C#, select
Windows. In the list of project templates, select Console Application. Name the project and click
OK.
![](http://i1.asp.net/media/3699352/httpclient04.png?cdn_id=2013-07-15-001)
Install NuGet Package Manager
NuGet Package Manager is the easiest way to add the Web API Client library to a project. If you do not have NuGet Package Manager already installed, install it as follows.Start Visual Studio.
From the Tools menu, select Extensions and Updates.
In the Extensions and Updates dialog, select Online.
If you don't see "NuGet Package Manager", type "nuget package manager" in the search box.
Select the NuGet Package Manager and click Download.
After the download completes, you will be prompted to install.
After the installation completes, you might be prompted to restart Visual Studio.
![](http://i3.asp.net/media/3202344/webapi_selfhost03.png?cdn_id=2013-07-15-001)
Install the Web API Client Libraries
After NuGet Package Manager is installed, add the Web API Client Libraries package to your project.From the Tools menu, select Library Package Manager.
Note: If do you not see this menu item, make sure that NuGet Package Manager installed correctly.
Select Manage NuGet Packages for Solution...
In the Manage NugGet Packages dialog, select Online.
In the search box, type "Microsoft.AspNet.WebApi.Client".
Select the package named "Microsoft ASP.NET Web API Client Libraries".
Click Install.
After the package installs, click Close to close the dialog.
![](http://i2.asp.net/media/3672696/httpclient02.png?cdn_id=2013-07-15-001)
Add the Model Class
Add the following class to the application:class Product { public string Name { get; set; } public double Price { get; set; } public string Category { get; set; } }
This class creates a data object that HttpClient will write into the HTTP request body and read from the HTTP response body.
Initialize HttpClient
Create a new instance of HttpClient and initialize it as follows:namespace ProductStoreClient { using System; using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; class Program { static void Main(string[] args) { HttpClient client = new HttpClient(); client.BaseAddress = new Uri("http://localhost:9000/"); // Add an Accept header for JSON format. client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); } } }
This code sets the base URI to "http://localhost:9000/", and sets the Accept header to "application/json", which tells the server to send data in JSON format.
Getting a Resource (HTTP GET)
The following code shows how to query the API for a list of products:// List all products. HttpResponseMessage response = client.GetAsync("api/products").Result; // Blocking call! if (response.IsSuccessStatusCode) { // Parse the response body. Blocking! var products = response.Content.ReadAsAsync<IEnumerable<Product>>().Result; foreach (var p in products) { Console.WriteLine("{0}\t{1};\t{2}", p.Name, p.Price, p.Category); } } else { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); }
The GetAsync method sends an HTTP GET request. As the name implies,
GetAsyc is asynchronous. It returns immediately, without waiting for a response from the server. The return value is a
Task object that represents the asynchronous operation. When the operation completes, the
Task.Result property contains the HTTP response.
It is important to understand that taking the Result property blocks your application thread until the request completes (or times out). Blocking in a console application is OK, but you should never do this on the UI thread of a Windows
application, because it blocks the UI from responding to user input. In the next part of this tutorial, we'll see how to write non-blocking calls.
If the HTTP response indicates success, the response body contains a list of products in JSON format. To parse the list, call
ReadAsAsync. This method reads the response body and tries to deserialize it to a specified CLR type. This method is also asynchronous, because the body can be arbitrarily large. Again, taking the
Result property blocks the thread.
Example HTTP session:
GET http://localhost:9000/api/products HTTP/1.1 Accept: application/json Host: localhost:9000 Connection: Keep-Alive HTTP/1.1 200 OK Server: ASP.NET Development Server/11.0.0.0 Date: Mon, 20 Aug 2012 22:14:59 GMT X-AspNet-Version: 4.0.30319 Cache-Control: no-cache Pragma: no-cache Expires: -1 Content-Type: application/json; charset=utf-8 Content-Length: 183 Connection: Close [{"Id":1,"Name":"Tomato soup","Category":"Groceries","Price":1.39},{"Id":2,"Name":"Yo-yo", "Category":"Toys","Price":3.75},{"Id":3,"Name":"Hammer","Category":"Hardware","Price":16.99}]
Getting a product by ID is similar:
// Get a product by ID response = client.GetAsync("api/products/1").Result; if (response.IsSuccessStatusCode) { // Parse the response body. Blocking! var product = response.Content.ReadAsAsync<Product>().Result; Console.WriteLine("{0}\t{1};\t{2}", product.Name, product.Price, product.Category); } else { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); }
Media-Type Formatters
ReadAsAsync is an extension method defined in the System.Net.Http.HttpContentExtensions class. With no parameters, it uses the default set of media-type formatters to try to parse the response body. The default formatterssupport JSON, XML, and Form-url-encoded data. (For more information about media-type formatters, see
Formats and Model Binding.)
You can also explicitly specify the media-types formatters to use. This is useful if you have a custom media-type formatter.
var formatters = new List<MediaTypeFormatter>() { new MyCustomFormatter(), new JsonMediaTypeFormatter(), new XmlMediaTypeFormatter() }; resp.Content.ReadAsAsync<IEnumerable<Product>>(formatters);
Creating a Resource (HTTP POST)
The following code sends a POST request that contains aProductinstance in JSON format:
// Create a new product var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" }; Uri gizmoUri = null; response = client.PostAsJsonAsync("api/products", gizmo).Result; if (response.IsSuccessStatusCode) { gizmoUri = response.Headers.Location; } else { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); }
PostAsJsonAsync is an extension method defined in System.Net.Http.HttpClientExtensions. It is equivalent to the following:
var product = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" }; // Create the JSON formatter. MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter(); // Use the JSON formatter to create the content of the request body. HttpContent content = new ObjectContent<Product>(product, jsonFormatter); // Send the request. var resp = client.PostAsync("api/products", content).Result;
For XML format, use the PostAsXmlAsync method.
Example HTTP session:
POST http://localhost:9000/api/products HTTP/1.1 Accept: application/json Content-Type: application/json; charset=utf-8 Host: localhost:9000 Content-Length: 50 Expect: 100-continue {"Name":"Gizmo","Price":100.0,"Category":"Widget"} HTTP/1.1 201 Created Server: ASP.NET Development Server/11.0.0.0 Date: Mon, 20 Aug 2012 22:15:00 GMT X-AspNet-Version: 4.0.30319 Location: http://localhost:9000/api/products/7 Cache-Control: no-cache Pragma: no-cache Expires: -1 Content-Type: application/json; charset=utf-8 Content-Length: 57 Connection: Close {"Id":7,"Name":"Gizmo","Category":"Widget","Price":100.0}
By default, the JSON formatter sets the content-type to "application/json". You can also specify the media type explicitly. For example, suppose that "application/vnd.example.product" is your media type for
Productinstances. You could set this media type as follows:
HttpContent content = new ObjectContent<Product>(product, jsonFormatter, "application/vnd.example.product+json");
Updating a Resource (HTTP PUT)
The following code sends a PUT request.// Update a product gizmo.Price = 99.9; response = client.PutAsJsonAsync(gizmoUri.PathAndQuery, gizmo).Result; Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
The PutAsJsonAsync method works like PostAsJsonAsync, except it sends a PUT request instead of POST.
Deleting a Resource (HTTP DELETE)
By now, you can probably predict how to send a DELETE request:// Delete a product response = client.DeleteAsync(gizmoUri).Result; Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
Like GET, a DELETE request does not have a request body, so you don't need to specify JSON or XML format.
Error Handling
HttpClient does not thrown an exception when it receives an HTTP response with an error code. Instead, theStatusCode property on the response contains the status code. Also, the
IsSuccessStatusCode property is true if the status is a success code (status codes in the range 200-299).
The previous examples used this pattern:
HttpResponseMessage response = client.GetAsync("api/products").Result; if (response.IsSuccessStatusCode) { // .... }
If you prefer to treat error codes as exceptions, call the EnsureSuccessStatusCode method. This method throws an exception if the response status is not a success code.
try { var resp = client.GetAsync("api/products").Result; resp.EnsureSuccessStatusCode(); // Throw if not a success code. // ... } catch (HttpRequestException e) { Console.WriteLine(e.Message); }
HttpClient can throw exceptions for other reasons, of course — for example, if the request times out.
Configuring HttpClient
To configure HttpClient, create aWebRequestHandler instance, set properties on it, and pass it to the
HttpClient constructor:
WebRequestHandler handler = new WebRequestHandler() { AllowAutoRedirect = false, UseProxy = false }; HttpClient client = new HttpClient(handler);
WebRequestHandler derives from HttpMessageHandler. You can also plug in custom message handlers by deriving from
HttpMessageHandler. For more information, see
HTTP Message Handlers.
Additional Resources
A console application makes it easy to see the code flow. However, the blocking calls are not good practice for applications with a graphical UI. To learn how to handle asynchronous operations inHttpClient without blocking, see
Calling a Web API From a WPF Application
参考资料
http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client
相关文章推荐
- Calling a Web API From a .NET Client (C#)
- Calling a Web API From a .NET Client (C#)
- Calling a Web API From a .NET Client (C#)
- Calling a Web API From a .NET Client
- Web API: Client: Call a Web API from a .net client
- [转]Calling an OData Service From a .NET Client (C#)
- Embed client-side JavaScript in an ASP.NET 1.1 web page from server side code
- Use C# to get JSON Data from the Web and Map it to .NET Class => Made Easy! 转
- 【收藏】本周ASP.NET英文技术文章推荐[03/23 - 04/05]:C#、Visual Studio、MVC、死锁、Web 2.0 API、jQuery、IIS7、FileUpload
- ASP.NET MVC Web API Post FromBody(Web API 如何正确 Post)
- posting-jsonobject-with-httpclient-from-web-api
- Atitit. .net c# web 跟clientwinform 的ui控件结构比較
- 利用eWebEditor提供的Client API实现在客户端与编辑器的交互(转自http://www.ewebeditor.net/documentation/)
- 微信移动支付V3开发详细教程服务端采用.net mvc webapi(C#)
- 详解C# WebApi 接口测试工具:WebApiTestClient
- ASP.NET MVC Web API Post FromBody(Web API 如何正确 Post)
- C#与.NET Framework, ASP.NET Web API RC版本新特性:Web API的帮助文档制作
- 实测 c# .net 中 httpwebrequest 和 httpclient 性能 区别 对比
- C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志
- A simple Test Client built on top of ASP.NET Web API Help Page