Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >WebApiClient基础

WebApiClient基础

原创
作者头像
老九
修改于 2018-10-10 01:52:28
修改于 2018-10-10 01:52:28
2.8K0
举报
文章被收录于专栏:WebApiClientWebApiClient

本章节为了方便读者的理解,相关例子将使用HttpApiClient静态类来创建http接口的代理类,但在生产环境中,使用HttpApiFactory静态来创建http接口的代理类更合理,也是非常有必要的。

1. GET/HEAD请求

1.1 Get请求简单例子

代码语言:txt
AI代码解释
复制
public interface IMyWebApi : IHttpApi
{
    // GET http://www.mywebapi.com/webapi/user?account=laojiu
    [HttpGet("http://www.mywebapi.com/webapi/user")]
    ITask<HttpResponseMessage> GetUserByAccountAsync(string account);
}

var client = HttpApiClient.Create<IMyWebApi>();
var response = await client.GetUserByAccountAsync("laojiu");

1.2 使用HttpHost特性

代码语言:txt
AI代码解释
复制
[HttpHost("http://www.mywebapi.com/")]
public interface IMyWebApi : IHttpApi
{
    // GET /webapi/user?account=laojiu
    [HttpGet("webapi/user")]
    ITask<HttpResponseMessage> GetUserByAccountAsync(string account);
}

如果接口IMyWebApi有多个方法且都指向同一服务器,可以将请求的域名抽出来放到HttpHost特性。

1.3 响应的json/xml内容转换为强类型模型

1.3.1 隐式转换为强类型模型
代码语言:txt
AI代码解释
复制
[HttpHost("http://www.mywebapi.com/")]
public interface IMyWebApi : IHttpApi
{
    // GET /webapi/user?account=laojiu
    [HttpGet("webapi/user")]    
    ITask<UserInfo> GetUserByAccountAsync(string account);
}

当方法的返回数据是UserInfo类型的json或xml文本,且响应的Content-Type为application/json或application/xml值时,方法的原有返回类型ITask(Of HttpResponseMessage)就可以声明为ITask(Of UserInfo)。

1.3.2 显式转换为强类型模型
代码语言:txt
AI代码解释
复制
[HttpHost("http://www.mywebapi.com/")]
public interface IMyWebApi : IHttpApi
{
    // GET /webapi/user?account=laojiu
    [HttpGet("webapi/user")]  
    [JsonReturn] // 指明使用Json处理返回值为UserInfo类型
    ITask<UserInfo> GetUserByAccountAsync(string account);
}

当方法的返回数据是UserInfo类型的json或xml文本,但响应的Content-Type可能不是期望的application/json或application/xml值时,就需要显式声明JsonReturn或XmlReturn特性。

2.请求URL

2.1 URL的格式

无论是GET还是POST等哪种http请求方法,都遵循如下的URL格式:

{Scheme}://{UserName}:{Password}@{Host}:{Port}{Path}{Query}{Fragment}

例如:http://account:password@www.baidu.com/path1/?p1=abc#tag

2.2 动态PATH

代码语言:txt
AI代码解释
复制
public interface IMyWebApi : IHttpApi
{
    // GET http://www.webapiclient.com/laojiu
    [HttpGet("http://www.webapiclient.com/{account}"]
    ITask<string> GetUserByAccountAsync(string account);
}

某些接口方法将路径的一个分段语意化,比如GET http://www.webapiclient.com/{account},这里不同的{account}代表不同账号下的个人信息,使用{参数名}声明路径,在请求前会自动从参数(或参数模型的同名属性)取值替换。

2.3 动态URL

代码语言:txt
AI代码解释
复制
public interface IMyWebApi : IHttpApi
{
    // GET {URL}
    [HttpGet]
    ITask<string> GetUserByAccountAsync([Url] string url);
    
    // GET {URL}?account=laojiu
    [HttpGet]
    ITask<string> GetUserByAccountAsync([Url] string url, string account);
}

如果请求URL在运行时才确定,可以将请求URL作为一个参数,使用Url特性修饰这个参数并作为第一个参数。

2.4 Query参数

2.4.1 多个query参数平铺
代码语言:txt
AI代码解释
复制
// GET /webapi/user?account=laojiu&password=123456
[HttpGet("webapi/user")]
ITask<UserInfo> GetUserAsync(string account, string password);
2.4.2 多个query参数合并到模型
代码语言:txt
AI代码解释
复制
public class LoginInfo
{
    public string Account { get; set; }
    public string Password { get; set; }         
}

// GET /webapi/user?account=laojiu&password=123456
[HttpGet("webapi/user")]
ITask<UserInfo> GetUserAsync(LoginInfo loginInfo);
2.4.3 多个query参数平铺+部分合并到模型
代码语言:txt
AI代码解释
复制
public class LoginInfo
{
    public string Account { get; set; }
    public string Password { get; set; }         
}

// GET /webapi/user?account=laojiu&password=123456&role=admin
[HttpGet("webapi/user")]
ITask<UserInfo> GetUserAsync(LoginInfo loginInfo, string role);
2.4.4 显式声明PathQuery特性
代码语言:txt
AI代码解释
复制
// GET /webapi/user?account=laojiu&password=123456&role=admin
[HttpGet("webapi/user")]
ITask<UserInfo> GetUserAsync(
    [PathQuery]LoginInfo loginInfo,
    [PathQuery]string role);

对于没有任何特性修饰的每个参数,都默认被PathQuery修饰,表示做为请求路径或请求参数处理,PathQuery特性可以设置Encoding、IgnoreWhenNull和DateTimeFormat多个属性。

3.POST/PUT/DELETE请求

3.1 使用Json或Xml提交

  • 使用XmlContent修饰强类型模型参数,表示提交xml
  • 使用JsonContent修饰强类型模型参数,表示提交json
代码语言:txt
AI代码解释
复制
// POST webapi/user  
// Body user的json文本
[HttpPost("webapi/user")]
ITask<UserInfo> AddUserWithJsonAsync([JsonContent] UserInfo user);

// PUT webapi/user  
// Body user的xml文本
[HttpPut("/webapi/user")]
ITask<UserInfo> UpdateUserWithXmlAsync([XmlContent] UserInfo user);

3.2 使用x-www-form-urlencoded提交

  • 使用FormContent修饰强类型模型参数
  • 使用FormField修饰简单类型参数
代码语言:txt
AI代码解释
复制
// POST webapi/user  
// Body Account=laojiu&Password=123456
[HttpPost("webapi/user")]
ITask<UserInfo> UpdateUserWithFormAsync(
    [FormContent] UserInfo user);

// POST webapi/user  
// Body Account=laojiu&Password=123456&fieldX=xxx
[HttpPost("webapi/user")]
ITask<UserInfo> UpdateUserWithFormAsync(
    [FormContent] UserInfo user, 
    [FormField] string fieldX);

3.3 使用multipart/form-data提交

  • 使用MulitpartContent修饰强类型模型参数
  • 使用MulitpartText修饰简单类型参数
  • 使用MulitpartFile类型作为提交的文件
代码语言:txt
AI代码解释
复制
// POST webapi/user  
[HttpPost("webapi/user")]
ITask<UserInfo> UpdateUserWithMulitpartAsync([MulitpartContent] UserInfo user);

// POST webapi/user  
[HttpPost("/webapi/user")]
ITask<UserInfo> UpdateUserWithMulitpartAsync(
    [MulitpartContent] UserInfo user, 
    [MulitpartText] string nickName,
    MulitpartFile file);

3.4 使用具体的HttpContent类型提交

代码语言:txt
AI代码解释
复制
// POST webapi/user  
// Body Account=laojiu&Password=123456
[HttpPost("webapi/user")]
ITask<UserInfo> UpdateUserWithFormAsync(
    FormUrlEncodedContent user);

// POST webapi/user  
// Body Account=laojiu&Password=123456&age=18
[HttpPost("webapi/user")]
ITask<UserInfo> UpdateUserWithFormAsync(
    FormUrlEncodedContent user,
    [FormField] int age);

如果参数是类型是HttpContent类型的子类,如StringContent、ByteArrayContent、StreamContent、FormUrlEncodedContent等等,则可以直接做为参数,但是必须放在其它参数的前面

4 PATCH请求

json patch是为客户端能够局部更新服务端已存在的资源而设计的一种标准交互,在RFC6902里有详细的介绍json patch,通俗来讲有以下几个要点: 1. 使用HTTP PATCH请求方法; 2. 请求body为描述多个opration的数据json内容; 3. 请求的Content-Type为application/json-patch+json;

4.1 WebApiClient例子

代码语言:txt
AI代码解释
复制
public interface IMyWebApi : IHttpApi
{
    [HttpPatch("http://www.mywebapi.com/webapi/user")]
    Task<string> PatchAsync(JsonPatchDocument<UserInfo> doc);
}


var doc = new JsonPatchDocument<UserInfo>();
doc.Replace(item => item.Account, "laojiu");
doc.Replace(item => item.Email, "laojiu@qq.com");
var client = HttpApiClient.Create<IMyWebApi>();
await client.PatchAsync(doc);
4.2 Asp.net 服务端例子
代码语言:txt
AI代码解释
复制
[HttpPatch]
public UserInfo Patch([FromBody] JsonPatchDocument<UserInfo> doc)
{
    // 此处user是从db查询获得
    var user = new UserInfo
    {
        Account = "_Account",
        Password = "_Password",
        Email = "_Email"
    };

    doc.ApplyTo(user);
    return user;
}

5. 参数及属性注解

这些注解特性的命名空间在WebApiClient.DataAnnotations,用于影响参数的序列化行为。

5.1 参数别名

代码语言:txt
AI代码解释
复制
public interface IMyWebApi : IHttpApi
{
    // GET http://www.mywebapi.com/webapi/user?_name=laojiu
    [HttpGet("http://www.mywebapi.com/webapi/user")]
    ITask<string> GetUserByAccountAsync(
        [AliasAs("_name")] string account);
}

5.2 参数模型属性注解

代码语言:txt
AI代码解释
复制
public class UserInfo
{
    public string Account { get; set; }

    // 别名
    [AliasAs("a_password")]
    public string Password { get; set; }

    // 时间格式,优先级最高
    [DateTimeFormat("yyyy-MM-dd")]
    [IgnoreWhenNull] // 值为null则忽略序列化
    public DateTime? BirthDay { get; set; }
    
    // 忽略序列化
    [IgnoreSerialized]
    public string Email { get; set; } 
    
    // 时间格式
    [DateTimeFormat("yyyy-MM-dd HH:mm:ss")]
    public DateTime CreateTime { get; set; }
}

6. 参数及参数属性输入验证

这些验证特性都有相同的基类ValidationAttribute,命名空间为System.ComponentModel.DataAnnotations,由netfx或corefx提供。

6.1 参数值的验证

代码语言:txt
AI代码解释
复制
[HttpGet("webapi/user/GetById/{id}")]
ITask<HttpResponseMessage> GetByIdAsync(
    [Required, StringLength(10)] string id);

id的参数要求必填且最大长度为10的字符串,否则抛出ValidationException的异常。

6.2 参数的属性值验证

代码语言:txt
AI代码解释
复制
public class UserInfo
{
    [Required]
    [StringLength(10, MinimumLength = 1)]
    public string Account { get; set; }

    [Required]
    [StringLength(10, MinimumLength = 6)]
    public string Password { get; set; }
}

[HttpPut("webapi/user/UpdateWithJson")]
ITask<UserInfo> UpdateWithJsonAsync(
    [JsonContent] UserInfo user);

当user参数不为null的情况,就会验证它的Account和Password两个属性,HttpApiConfig有个UseParameterPropertyValidate属性,设置为false就禁用验证参数的属性值。

6.3 两者同时验证

对于上节的例子,如果我们希望user参数值也不能为null,可以如下声明方法:

代码语言:txt
AI代码解释
复制
[HttpPut("webapi/user/UpdateWithJson")]
ITask<UserInfo> UpdateWithJsonAsync(
    [Required, JsonContent] UserInfo user);

7.特性的范围和优先级

7.1 特性的范围

有些特性比如Header,可以修饰于接口、方法和参数,使用不同的构造器和修饰于不同的地方产生的含义和结果是有点差别的:

  • 修饰接口时,表示接口下的所有方法在请求前都会添加这个请求头;
  • 修饰方法时,表示此方法在请求前添加这个请求头;
  • 修饰参数时,表示参数的值将做为请求头的值,由调用者动态传入;

7.2 特性的优先级

  • 方法级比接口级优先级高;
  • AllowMultiple为true时,方法级和接口级都生效;
  • AllowMultiple为false时,方法级的生效,接口级的无效;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
WebApiClient高级
这是一个用于调试追踪的过滤器,可以将请求与响应内容写入统一日志,统一日志工厂需要在HttpApiConfig的LoggerFactory配置。
老九
2018/10/09
1.8K0
集高性能高可扩展性于一体的声明式http客户端库-WebApiClientCore
WebApiClient.JIT/AOT[1]的.NET Core版本,集高性能高可扩展性于一体的声明式http客户端库,特别适用于微服务的restful资源请求,也适用于各种畸形http接口请求。
郑子铭
2023/09/28
7410
集高性能高可扩展性于一体的声明式http客户端库-WebApiClientCore
WebApi client 的面向切面编程
.Net的面向切面编程 .Net的服务端应用AOP很常见,在Asp.net MVC与Asp.net WebApi等新框架里到处都有AOP的影子,我们可以把一个服务方法“切”为很多面,日志面、验证面、请求方式处理、接口业务实现等多个面,有一些面可以使用过滤器特性(FilterAttribute)进行编写,然后很方便和打上特性即可,对于一般的工程师,只需要专注实现接口业务实现。 在流行SOAP的年代,很少需要一个强悍的Client,而今天restful时代,.net也出了一个HttpClient,可以说是与As
企鹅号小编
2018/02/07
8810
Dapr 客户端 搭配 WebApiClientCore 玩耍服务调用
public interface IBank { [HttpGet("/accounts/{accountId}")] Task<Account> GetUser(string accountId, CancellationToken cancellationToken = default);
张善友
2021/08/10
6890
WebApiClient进阶
你应该尽量将得到的myWebApi保持为全局变量,多次请求里共用一个myWebApi实例。如果频繁地每次请求都创建和释放myWebApi,实际等同于短连接到服务器,客户端和服务器的性能都受到影响。但全局单例的myWebApi可能不遵循守DNS生存时间(TTL)设置,请求的域名指向的ip变化之后,会产生不正确的请求。
老九
2018/10/09
1.6K1
.NET Core微服务之服务间的调用方式(REST and RPC)
  微服务之间的接口调用通常包含两个部分,序列化和通信协议。常见的序列化协议包括json、xml、hession、protobuf、thrift、text、bytes等;通信比较流行的是http、soap、websockect,RPC通常基于TCP实现,常用框架例如dubbo,netty、mina、thrift。
Edison Zhou
2018/08/02
2.4K0
.NET Core微服务之服务间的调用方式(REST and RPC)
Apache HttpClient 5 使用详细教程
超文本传输协议(HTTP)可能是当今互联网上最重要的协议之一,Web 服务、微服务以及支持网络的各种设备上的服务几乎都是 HTTP 协议,HTTP 协议已经从 Web 浏览器走向了更广泛的使用场景。
未读代码
2022/11/21
6.8K0
Apache HttpClient 5 使用详细教程
【愚公系列】2023年10月 .NET CORE工具案例-HTTP请求之WebApiClientCore
WebApiClientCore是WebApiClient.JIT/AOT1的.NET Core版本,集高性能高可扩展性于一体的声明式http客户端库,特别适用于微服务的restful资源请求,也适用于各种畸形http接口请求。
愚公搬代码
2023/10/10
1.8K0
C#进阶系列——WebApi接口测试工具:WebApiTestClient
前言:这两天在整WebApi的服务,由于调用方是Android客户端,Android开发人员也不懂C#语法,API里面的接口也不能直接给他们看,没办法,只有整个详细一点的文档呗。由于接口个数有点多,每个接口都要详细说明接口作用、参数类型、返回值类型等等,写着写着把博主惹毛了,难道这种文档非要自己写不成?难道网上没有这种文档的展示工具吗?带着这两个问题,在网络世界里寻找,网络世界很奇妙,只要你用心,总能找到或多或少的帮助!这不就被博主找到了这个好用的组件:WebApiTestClient。它对于接口的作用、参
逸鹏
2018/04/10
1.8K0
C#进阶系列——WebApi接口测试工具:WebApiTestClient
实战 ASP.NET Web API
Web API 框架是一个面向 Http 协议的通信框架。相对于 WCF 而言,Web API 只面向于 Http 协议设计,而且没有 WCF 那么繁琐的配置。Web API 的开发类似于 ASP.NET MVC 中控制器的开发,但是相对于直接使用 ASP.NET MVC 来返回 Json 对象的方式而言,Web API 封装了数据的序列化、反序列化,接口、实现都更加简单。 简单地说,如果要向浏览器、移动端提供 Json 数据格式的 API,则应该首选 Web API 作为通信框架。 以下,我列出了在当前
用户1172223
2018/01/29
1.5K0
实战 ASP.NET Web API
C# HttpClient 请求认证、数据传输笔记
客户端请求服务器时,需要通过授权认证许可,方能获取服务器资源,目前比较常见的认证方式有 Basic 、JWT、Cookie。
痴者工良
2021/04/26
2.6K0
Magicodes.Wx.Sdk之30秒编写一个微信接口
Magicodes.Wx.Sdk致力于打造最简洁最易于使用的微信Sdk,逐步包括公众号Sdk、小程序Sdk、企业微信Sdk等,以及Abp VNext集成。
心莱科技雪雁
2021/03/25
5110
ASP.NET Web API 应用教程(一) ——数据流使用
相信已经有很多文章来介绍ASP.Net Web API 技术,本系列文章主要介绍如何使用数据流,HTTPS,以及可扩展的Web API 方面的技术,系列文章主要有三篇内容。 主要内容如下: I  数据流 II 使用HTTPS III 可扩展的Web API 文档 项目环境要求 VS 2012(SP4)及以上, .Net 框架4.5.1 Nuget包,可在packages.config 文件中查寻 本文涉及的知识点 ActionFilter AuthorizationFilter DelegateHand
葡萄城控件
2018/01/10
2.4K0
ASP.NET  Web API 应用教程(一) ——数据流使用
Java:HttpClient篇,HttpClient4.2在Java中的几则应用:Get、Post参数、Session(会话)保持、Proxy(代理服务器)设置,多线程设置...
新版HttpClient4.2与之前的3.x版本有了很大变化,建议从http://hc.apache.org/处以得到最新的信息。
bear_fish
2018/09/19
2.5K0
C#进阶系列——WebApi 接口参数不再困惑:传参详解上
前言:还记得刚使用WebApi那会儿,被它的传参机制折腾了好久,查阅了半天资料。如今,使用WebApi也有段时间了,今天就记录下API接口传参的一些方式方法,算是一个笔记,也希望能帮初学者少走弯路。本篇针对初初使用WebApi的同学们,比较基础,有兴趣的且看看。 WebApi系列文章 C#进阶系列——WebApi接口测试工具:WebApiTestClient C#进阶系列——WebApi 跨域问题解决方案:CORS C#进阶系列——WebApi身份认证解决方案:Basic基础认证 C#进阶系列——WebAp
逸鹏
2018/04/10
5.5K0
C#进阶系列——WebApi 接口参数不再困惑:传参详解上
快速入门系列--WebAPI--01基础
ASP.NET MVC和WebAPI已经是.NET Web部分的主流,刚开始时两个公用同一个管道,之后为了更加的轻量化(WebAPI是对WCF Restful的轻量化),WebAPI使用了新的管道,因此两者相关类的命名空间有细微差异,在使用时需要注意。 WebAPI学习系列目录如下,欢迎您的阅读! 快速入门系列--WebAPI--01基础 快速入门系列--WebAPI--02进阶 快速入门系列--WebAPI--03框架你值得拥有 快速入门系列--WebAPI--04在老版本MVC4下的调整 WebA
用户1216676
2018/01/24
2.4K0
快速入门系列--WebAPI--01基础
小范笔记:ASP.NET Core API 基础知识与Axios前端提交数据
跟同事合作前后端分离项目,自己对 WebApi 的很多知识不够全,虽说不必要学全栈,可是也要了解基础知识,才能合理设计接口、API,方便与前端交接。
痴者工良
2019/07/04
5.7K0
asp.net web api客户端调用
服务接口 接口1: //Post:http://127.0.0.1/HY_WebApi/api/V2/Key/FunctionTest1 [HttpPost] public HttpResponseMessage FunctionTest1(Model1 model) { ...... } 接口2: //Post:http://127.0.0.1/HY_WebApi/api/V2/Key/FunctionTest2 [HttpPost] public HttpResponseMess
甜橙很酸
2018/03/08
3.5K0
ASP.NET Web API编程——模型验证与绑定
1.模型验证 使用特性约束模型属性 可以使用System.ComponentModel.DataAnnotations提供的特性来限制模型。 例如,Required特性表示字段值不能为空,Range特性限制数值类型的范围。 对实体类使用特性后,可以使用ModelState.IsValid来判断验证是否通过。 例: 实体: public class DataModel { public int Id { get; set; } public string Field1Nam
甜橙很酸
2018/04/18
3.1K0
ASP.NET Web API编程——模型验证与绑定
【代替Swagger和Postman等工具的神器】使用VS自带的.http文件快速调试webapi
前言:需要VS2022版本支持。.http文件在.NET 8环境下自带,但是处于好奇心挖掘了一下,其实这个文件和你是啥SDK环境无关、和啥开发语言也无关,纯粹就是VS2022里面附带的功能。废话不多说,下面正文:
Wesky
2024/08/13
2550
【代替Swagger和Postman等工具的神器】使用VS自带的.http文件快速调试webapi
推荐阅读
相关推荐
WebApiClient高级
更多 >
LV.0
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档