一、什么是WebAPI?
1.1-什么是WebAPI?
WebAPI是一种用开发系统接口、设备接口API的技术,基于Http协议,请求和返回格式默认是Json格式。比WCF简单、更通用;比WebService更节省流量,更简洁。
1.2-WebAPI的特点?
- Action方法直接返回对象,专注于数据
- 更符合Restful的风格
- 有利于独立于IIS部署
- Action可以直接声明为async
二、什么是Restful?
2.1-传统的Http接口怎么设计?
2.2-Http设计之初"谓词语义"?
- GET:查询获取
- POST:添加
- Put:修改
- Delete:删除
2.3-Http设计之初"谓词语义"带来的好处是什么?
- 为不同的请求做不同的权限的控制;
- 不需要"Delete","AddNew"这样的Action名字,根据请求的类型就可以判断
- 返回报文的格式也确定,不用在约定返回状态码,充分利用Http状态码
- 有利于系统优化,浏览器可以自动缓存Get请求
- Get没有副作用,是幂等的,可以重试。
注意:返回结果尽量根据Http状态码返回。
三、简单的WebAPI(.NET Framework)
3.1-简单WebAPI和是使用异步方式调用
/// <summary>
/// 需要继承自ApiController
/// </summary>
public class PersonController : ApiController
{
public string[] Get() {
return new string[] { "西瓜程序猿", "Albert" };
}
public string Get(int id) {
return $"Haha:" + id;
}
public string Get(string name) {
return name;
}
}
}
3.2-WebAPI的参数
3.3-WebAPI的返回值
/// <summary>
/// HttpResponseMessage类型
/// 返回报文头、内容等等信息(控制相应的内容)
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("Test3")]
public HttpResponseMessage Test3() {
HttpResponseMessage msg = new HttpResponseMessage();
msg.Content =new StringContent( "报文体");
msg.Headers.Add("Haha", "这是请求头体");
msg.StatusCode = System.Net.HttpStatusCode.OK;
msg.Headers.Age = TimeSpan.FromDays(3);
return msg;
}
3.4-通过自定义路由处理API多版本
3.5-通过ControllerSelector实现多版本(配置路由规则)
(1)创建2个版本控制器
(2)在【WebApiConfig】的Register中,添加1个路由规则,并替换IHttpControllerSelector
config.Routes.MapHttpRoute(
name: "DefaultApiV1",
routeTemplate: "api/v1/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//添加一个路由规则
config.Routes.MapHttpRoute(
name: "DefaultApiV2",
routeTemplate: "api/v2/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//替换
config.Services.Replace(typeof(IHttpControllerSelector), new VersionControllerSelector(config));
(3)VersionControllerSelector.cs代码如下:
namespace Demo
{
/// <summary>
/// 用来控制API版本
/// 需要继承自DefaultHttpControllerSelector
/// </summary>
public class VersionControllerSelector : DefaultHttpControllerSelector
{
private readonly HttpConfiguration _config;
private IDictionary<string, HttpControllerDescriptor> _ctlMapping;
public VersionControllerSelector(HttpConfiguration config) : base(config)
{
this._config = config;
}
public override IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
{
Dictionary<string, HttpControllerDescriptor> dict = new Dictionary<string, HttpControllerDescriptor>();
//加载所有程序集,然后遍历
foreach (var asm in _config.Services.GetAssembliesResolver().GetAssemblies())
{
//获得程序集所有的类,并且该类不是抽象类,并且继承自ApiController
var controllerTypes = asm.GetTypes().Where(u => u.IsAbstract == false && typeof(ApiController).IsAssignableFrom(u));
//遍历并生成名字
foreach (var ctrlType in controllerTypes)
{
string ctrolTypeNS = ctrlType.Namespace;//获取命名空间名称
var match = Regex.Match(ctrolTypeNS, @"\.v(\d)");//获得需要的名称
if (!match.Success)
{
continue;
}
string verNum = match.Groups[1].Value;//拿到版本号1提取出来
string ctrlTypeName = ctrlType.Name;//拿到类名(PersonController)
//拿到匹配的类型
var matchController = Regex.Match(ctrlTypeName, @"^(.+)Controller$");
if (!matchController.Success)
{
continue;
}
string ctrlName = matchController.Groups[1].Value;//得到合法的PersonController
string key = ctrlName + "v" + verNum;
dict[key] = new HttpControllerDescriptor(_config, ctrlName,ctrlType);
}
}
_ctlMapping = dict;
return dict;
}
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
//拿到controller
string controller =(string)request.GetRouteData().Values["controller"];
if (_ctlMapping == null) {
//调用之前的方法拿到,key/value
_ctlMapping = GetControllerMapping();
}
// /api/v1/person
var matchVer = Regex.Match(request.RequestUri.PathAndQuery, @"/v(\d+)/");
if (!matchVer.Success) {
//我处理不了,让父类处理
return base.SelectController(request);
}
string verNum = matchVer.Groups[1].Value;//2
string key = controller + "v" + verNum;
if (_ctlMapping.ContainsKey(key))
{
return _ctlMapping[key];
}
else {
//我处理不了,让父类处理
return base.SelectController(request);
}
}
}
}
3.6-WebAPI中Filter-简单判断是否授权
(1)新建一个类。
(2)类的代码如下:
namespace Demo.Filter
{
public class MyAuthorFilter : IAuthorizationFilter
{
public bool AllowMultiple => true;
public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
IEnumerable<string> userNames;
if (!actionContext.Request.Headers.TryGetValues("UserName", out userNames)){
//返回未授权状态码
return new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
};
string userName = userNames.First();
if (userName == "admin")
{
return await continuation();
}
else {
//返回未授权状态码
return new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
}
}
}
(3)在【WebApiConfig.cs】的Register方法进行注册自定义的Filter。
//注册自己写的Filter
config.Filters.Add(new MyAuthorFilter());
3.7-WebAPI的异常处理
系统错误:
业务错误:
3.8-接口的安全性问题
3.9-JWT介绍
3.10-接口安全传输
版权声明:本文为原创文章,版权归 [西瓜程序猿] 所有,转载请注明出处,有任何疑问请私信咨询。
原文链接:https://blog.csdn.net/2301_79251107/article/details/132118366