可以使用HttpClient这个调用Web API,下面是HttpClient的定义,列举了一些常用的方法,其中还有一些没有列举,包括重载的方法。

  1. public class HttpClient : HttpMessageInvoker
  2. {
  3. public HttpClient();
  4. public HttpClient(HttpMessageHandler handler);
  5.  
  6. //统一资源标识符 (URI) 的基地址
  7. public Uri BaseAddress { get; set; }
  8. //获取或设置请求超时前等待的毫秒数
  9. public TimeSpan Timeout { get; set; }
  10.  
  11. //发送异步GET请求
  12. public Task<HttpResponseMessage> GetAsync(Uri requestUri);
  13. //发送异步POST请求
  14. public Task<HttpResponseMessage> PostAsync(Uri requestUri, HttpContent content);
  15. //发生异步请求,可以指定HTTP动作
  16. public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request);
  17. }

HttpClient的使用

上面几个方法GetAsync、PostAsync、SendAsync的返回值类型都是Task<HttpResponseMessage>,可以调用Task<TResult>.Result属性获得类型为HttpResponseMessage的实例。HttpResponseMessage的Content属性有一个异步方法ReadAsStringAsync可以获得响应消息体的内容(服务端传过来的字符串),使用ReadAsAsync<T>方法已获得反序列化后的CLR类型数据。

例:读取字符串。

为了看清返回类型,客户端每个方法的调用返回值赋给一个强类型的变量,方便观察返回值和理解,也可以将返回值变量赋给一个var类型的变量。

客户端:

  1. public static void TestClient()
  2. {
  3. string url = "http://localhost/webApi_test/api/testapi";
  4. using (HttpClient client = new HttpClient())
  5. {
  6. Task<HttpResponseMessage> taskResult = client.GetAsync(url);
  7. HttpResponseMessage responseMessage = taskResult.Result;
  8. Task<string> contentStr = responseMessage.Content.ReadAsStringAsync();
  9. contentStr.Wait();
  10. Console.WriteLine(contentStr.Result);
  11. }
  12. Console.ReadLine();
  13. }

服务端:

  1. public class TestApiController : ApiController
  2. {
  3. public IHttpActionResult Get()
  4. {
  5. return Ok("hello web api client");
  6. }
  7. }

路由配置:

  1. config.Routes.MapHttpRoute(
  2. name: "DefaultApi",
  3. routeTemplate: "api/{controller}/{id}",
  4. defaults: new { id = RouteParameter.Optional }
  5. );

例:获得实体,并序列化显示

调用响应的Content.ReadAsAsync<T>方法获得实体。

客户端:

  1. public static void TestClient()
  2. {
  3. string url = "http://localhost/webApi_test/api/testapi/1";
  4. using (HttpClient client = new HttpClient())
  5. {
  6. Task<HttpResponseMessage> taskResult = client.GetAsync(url);
  7. HttpResponseMessage responseMessage = taskResult.Result;
  8. Task<DataModel> model = responseMessage.Content.ReadAsAsync<DataModel>();
  9. model.Wait();
  10. Console.WriteLine(JsonConvert.SerializeObject(model.Result,Formatting.Indented));
  11. }
  12. Console.ReadLine();
  13. }

服务端(路由配置同上):

  1. public IHttpActionResult Get(int id = )
  2. {
  3. DataModel model = new DataModel { Id = id, Field1Name = "f1", Field2Name = "f2", DT = DateTime.Now };
  4. return Ok(model);
  5. }

返回结果:

例:客户端向服务端传递复杂数据。

使用SendAsync方法,但是注意无法发送GET和HEAD请求。下面的例子向服务端发送PUT请求,并且将发送给服务端的数据放入了请求消息的消息体中,为了让服务端获取消息体内容的格式信息以便其选择多媒体格式化器绑定模型,将HttpContent.Headers.ContentType设置为application/json类型,因为向请求消息体中写入的是JSON格式的字符串。

客户端:

  1. public static void TestClient()
  2. {
  3. string url = "http://localhost/webApi_test/api/testapi";
  4. var modelRequest = new { Id = , Field1Name = "1name", Field2Name = "2name", DT = DateTime.Now };
  5. using (HttpClient client = new HttpClient())
  6. {
  7. using (HttpContent content = new StringContent(JsonConvert.SerializeObject(modelRequest)))
  8. {
  9. content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  10. using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, url))
  11. {
  12. request.Content = content;
  13. Task<HttpResponseMessage> taskResult = client.SendAsync(request);
  14. HttpResponseMessage responseMessage = taskResult.Result;
  15. Task<DataModel> model = responseMessage.Content.ReadAsAsync<DataModel>();
  16. model.Wait();
  17. Console.WriteLine(JsonConvert.SerializeObject(model.Result, Formatting.Indented));
  18. }
  19. }
  20. }
  21. Console.ReadLine();
  22. }

服务端:

  1. public IHttpActionResult Put(DataModel model)
  2. {
  3. return Ok(model);
  4. }

路由:

  1. config.Routes.MapHttpRoute(
  2. name: "DefaultApi",
  3. routeTemplate: "api/{controller}/{id}",
  4. defaults: new { id = RouteParameter.Optional }

例:将数据写入请求消息体的方式

有几种方式为HttpRequestMessage.Content属性赋值,可以使用FormUrlEncodedContent、StringContent,他们都派生自ByteArrayContent。FormUrlEncodedContent指定的多媒体格式为application/x-www-form-urlencoded,如果将写入请求消息体的内容格式设置为application/x-www-form-urlencoded,即HttpContent.Headers.ContentType = application/x-www-form-urlencoded,可以正常传递数据,不设置就默认指定为application/x-www-form-urlencoded类型。

客户端调用

  1. var list = new List<KeyValuePair<string, string>>
  2. {
  3. new KeyValuePair<string, string>("Field21", "f1"),
  4. new KeyValuePair<string, string>("Field22", "f2")
  5. };
  6. using (HttpClient client = new HttpClient())
  7. {
  8. using (HttpContent content = new FormUrlEncodedContent(list))
  9. {
  10. content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
  11. using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url))
  12. {
  13. request.Content = content;
  14. Task<HttpResponseMessage> taskResult = client.SendAsync(request);
  15. HttpResponseMessage responseMessage = taskResult.Result;
  16. Task<Model2> model = responseMessage.Content.ReadAsAsync<Model2>();
  17. model.Wait();
  18. Console.WriteLine(JsonConvert.SerializeObject(model.Result, Formatting.Indented));
  19. }
  20. }
  21. }
  22. Console.ReadLine();

服务器:

  1. public IHttpActionResult Post(Model2 model)
  2. {
  3. return Ok(model);
  4. }
  5.  
  6. public class Model2
  7. {
  8. public string Field21 { get; set; }
  9. public string Field22 { get; set; }
  10. }

运行结果:

如果将上述客户端代码的content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

改为:content.Headers.ContentType = new MediaTypeHeaderValue("application/json"),则服务端无法正常为操作参数赋值:

此外FormUrlEncodedContent不适合传递集合或数据模型中属性为集合类型的实体。如下面的实体类型,若服务端接收的参数类型为Model1,则不适合使用FormUrlEncodedContent。而应使用StringContent

  1. public class Model1
  2. {
  3. public List<Model2> List1 { get; set; }
  4. public string Name { get; set; }
  5. }
  6.  
  7. public class Model2
  8. {
  9. public string Field21{get;set;}
  10. public string Field22{get;set;}
  11. }

例:使用HttpClientExtensions

HttpClientExtensions提供了HttpClient的扩展方法,PostAsJsonAsync<T>可以将实体T序列化为JSON格式放入请求消息体中,同样地PutAsJsonAsync也如此,只不过前者发送POST请求后者发送PUT请求。另外,他们的重载方法可以指定多媒体格式化器。

客户端:

  1. string url = "http://localhost/webApi_test/api/testapi";
  2. List<Model2> model2List = new List<Model2> { new Model2 { Field21 = "f1", Field22 = "f2" }, new Model2 { Field21 = "f21", Field22 = "f22" } };
  3. Model1 model = new Model1 { Name = "集合", List1 = model2List };
  4.  
  5. using (HttpClient client = new HttpClient())
  6. {
  7. Task<HttpResponseMessage> taskResult = client.PostAsJsonAsync(url,model);
  8. HttpResponseMessage responseMessage = taskResult.Result;
  9. Task<Model1> models = responseMessage.Content.ReadAsAsync<Model1>();
  10. models.Wait();
  11. Console.WriteLine(JsonConvert.SerializeObject(models.Result, Formatting.Indented));
  12. }
  13. Console.ReadLine();

服务端:

  1. public IHttpActionResult Post(Model1 model)
  2. {
  3. return Ok(model);
  4. }
  5.  
  6. public class Model1
  7. {
  8. public List<Model2> List1 { get; set; }
  9. public string Name { get; set; }
  10. }
  11.  
  12. public class Model2
  13. {
  14. public string Field21 { get; set; }
  15. public string Field22 { get; set; }
  16. }

结果:

指定格式化器,下面例子指定了JSON格式化器,也可以指定BSON格式化器。

  1. string url = "http://localhost/webApi_test/api/testapi";
  2. List<Model2> model2List = new List<Model2> { new Model2 { Field21 = "f1", Field22 = "f2" }, new Model2 { Field21 = "f21", Field22 = "f22" } };
  3. Model1 model = new Model1 { Name = "集合", List1 = model2List };
  4.  
  5. using (HttpClient client = new HttpClient())
  6. {
  7. Task<HttpResponseMessage> taskResult = client.PostAsync(url, model, new JsonMediaTypeFormatter());
  8. HttpResponseMessage responseMessage = taskResult.Result;
  9. Task<Model1> models = responseMessage.Content.ReadAsAsync<Model1>();
  10. models.Wait();
  11. Console.WriteLine(JsonConvert.SerializeObject(models.Result, Formatting.Indented));
  12. }
  13. Console.ReadLine();

指定BSON格式化器,并且解析响应时也要指定为BOSN格式化器,同时需要注意的是,Web API默认配置没有包含BSON格式化器,所以要在服务端添加BSON格式化器。

  1. string url = "http://localhost/webApi_test/api/testapi";
  2. List<Model2> model2List = new List<Model2> { new Model2 { Field21 = "f1", Field22 = "f2" }, new Model2 { Field21 = "f21", Field22 = "f22" } };
  3. Model1 model = new Model1 { Name = "集合", List1 = model2List };
  4.  
  5. using (HttpClient client = new HttpClient())
  6. {
  7. Task<HttpResponseMessage> taskResult = client.PostAsync(url, model, new BsonMediaTypeFormatter());
  8. HttpResponseMessage responseMessage = taskResult.Result;
  9. Task<Model1> models = responseMessage.Content.ReadAsAsync<Model1>(new List<BsonMediaTypeFormatter> { new BsonMediaTypeFormatter() });
  10. models.Wait();
  11. Console.WriteLine(JsonConvert.SerializeObject(models.Result, Formatting.Indented));
  12. }
  13. Console.ReadLine();

---------------------------------------------------------------------

转载与引用请注明出处。

时间仓促,水平有限,如有不当之处,欢迎指正。

ASP.NET Web API编程——客户端调用的更多相关文章

  1. ASP.NET Web API编程——路由

    路由过程大致分为三个阶段: 1)请求URI匹配已存在路由模板 2)选择控制器 3)选择操作 1匹配已存在的路由模板 路由模板 在WebApiConfig.Register方法中定义路由,例如模板默认生 ...

  2. ASP.NET Web API编程——序列化与内容协商

    1 多媒体格式化器 多媒体类型又叫MIME类型,指示了数据的格式.在HTTP协议中多媒体类型描述了消息体的格式.一个多媒体类型包括两个字符串:类型和子类型. 例如: text/html.image/p ...

  3. asp.net web api 向客户端返回错误信息

    1使用Http状态码 ASP.NET Web Api框架提供了Http状态码的值,如下图所示. 虽然有这些预定义的状态码,但在实际项目中使用自定状态码结合预定义状态码更有优势. 通过在适当的位置抛出异 ...

  4. ASP.NET Web API编程——构建api帮助文档

    1 概要 创建ASP.NET Web Api 时模板自带Help Pages框架. 2 问题 1)使用VS创建Web Api项目时,模板将Help Pages框架自动集成到其中,使得Web Api项目 ...

  5. ASP.NET Web API编程——模型验证与绑定

    1.模型验证 使用特性约束模型属性 可以使用System.ComponentModel.DataAnnotations提供的特性来限制模型. 例如,Required特性表示字段值不能为空,Range特 ...

  6. ASP.NET Web API编程——文件上传

    首先分别介绍正确的做法和错误的做法,然后分析他们的不同和错误之处,以便读者在实现此功能时可避开误区 1正确的做法 public class AvaterController : BaseApiCont ...

  7. ASP.NET Web API编程——异常捕获

    1 向客户端发送错误消息 使用throw new HttpResponseException()向客户端抛出错误信息. HttpResponseException包含两个重载的构造函数,其中一个是构造 ...

  8. ASP.NET Web API编程——文件下载

    断点续传基本原理 HTTP协议中与断点续传相关的HTTP头为:Range和Content-Range标头,断点续传实现流程: 1)客户端请求下载一个文件,文件的总长度为n:已经下载了一部分文件,长度为 ...

  9. ASP.NET Web API 实现客户端Basic(基本)认证 之简单实现

    优点是逻辑简单明了.设置简单. 缺点显而易见,即使是BASE64后也是可见的明文,很容易被破解.非法利用,使用HTTPS是一个解决方案. 还有就是HTTP是无状态的,同一客户端每次都需要验证. 实现: ...

随机推荐

  1. 开窗函数over()

    使用方法 如:select name,avg(shengao)from xinxi group by name //我们都知道使用聚合函数要使用分组,如果不分组怎么办 Selct name,avg(s ...

  2. golang学习之win7下go web之revel安装

    接着上回记录的win7下go环境搭建,go的开发,现在除了sublime外,LiteIDE比较推荐,下载链接 下载安装后直接打开,需要配置下go环境(本机使用的是window 386版本),如下: 打 ...

  3. mysql表情存储报错问题

    mysql采用utf-8字符编码,但在移动端使用输入法的表情并存储数据库的时候,出现错误. java.sql.SQLException: Incorrect string value: '\xF0\x ...

  4. MySql数据快速导入

    使用LOAD DATA INFILE 插入速度可以提升很多 左侧是直接导入100W花费135s ,Dos界面通过Load方式导入450W只用时23s,性能一下子显示出来了.

  5. sql server or Oracle: table MS_Description

    --SQL Server表描述 及 字段描述的增.删.改.查询 --sql server 2000系统表sysproperties在SQL 2008中无效的问题 今天无意中在网上发现Sqlserver ...

  6. css的字体样式怎么写

    为保证字体的正常加载 sans-serif不能丢 font-family:'MicrosoftYahei','微软雅黑',Arial,'宋体',sans-serif;

  7. 解决Maven引用POI的依赖,XSSFWorkbook依旧无法使用的问题

    Java项目,导入Excel数据功能,第一次使用POI,一开始就遇到了小麻烦! Maven项目引用POI的jar包 <!-- https://mvnrepository.com/artifact ...

  8. Java基础学习总结一(Java语言发展历史、JDK下载安装以及配置环境变量)

    最近一段时间计划复习一下java基础知识,使用的视频课程是尚学堂高淇老师的,上课过程中的心得体会直接总结一下,方便以后复习. 一:计算机语言的发展 1:机器语言,最原始的语言,主要有“01”构成,最早 ...

  9. Java入门到精通——调错篇之Astah Community打开报需要jre1.7运行环境

    1.问题概述     Astah Community安装完以后点击运行Astah Community的时候报此应用需要jdk1.7如下图     但是我的电脑在D盘装了jdk1.8了为什么这个软件为什 ...

  10. Java中由Calendar类获取的月、天和小时的简单处理

    在Java中,Calendar是日期处理的一个重要的类.但是,我们使用Calendar获取的月份,天,小时等可能需要进行简单的处理才能满足我们的需要.比如,月份范围是0-11,而我们可能需要的是1-1 ...