笔记源于课堂编写:BiliBili
源视频教程:https://www.bilibili.com/video/BV12v411i7wx

一、什么是WebAPI?

1.1-什么是WebAPI?

WebAPI是一种用开发系统间接口、设备接口API的技术,基于Http协议,请求和返回格式默认是Json格式。比WCF简单、跟更通用;比WebService更节省流量,更简洁。

1.2-WebAPI的特点?

  • Action方法直接返回对象,专注于数据
  • 更符合Restful的风格
  • 有利于独立于IIS部署
  • Action可以直接声明为async

二、什么是Restful?

2.1-传统的Http接口怎么设计?

009.1-ASP.NET WebAPI - 图1

2.2-Http设计之初”谓词语义”?

  • GET:查询获取
  • POST:添加
  • Put:修改
  • Delete:删除

2.3-Http设计之初”谓词语义”带来的好处是什么?

  • 为不同的请求做不同的权限的控制;
  • 不需要”Delete”,”AddNew”这样的Action名字,根据请求的类型就可以判断
  • 返回报文的格式也确定,不用在约定返回状态码,充分利用Http状态码
  • 有利于系统优化,浏览器可以自动缓存Get请求
  • Get没有副作用,是幂等的,可以重试。

//返回结果尽量根据Http状态码返回。

三、简单的WebAPI(.NET Framework)

3.1-简单WebAPI和是使用异步方式调用

  1. /// <summary>
  2. /// 需要继承自ApiController
  3. /// </summary>
  4. public class PersonController : ApiController
  5. {
  6. public string[] Get() {
  7. return new string[] { "滔滔程序猿", "Albert" };
  8. }
  9. public string Get(int id) {
  10. return $"Haha:" + id;
  11. }
  12. public string Get(string name) {
  13. return name;
  14. }
  15. }
  16. }

009.1-ASP.NET WebAPI - 图2

3.2-WebAPI的参数

009.1-ASP.NET WebAPI - 图3
009.1-ASP.NET WebAPI - 图4
009.1-ASP.NET WebAPI - 图5
009.1-ASP.NET WebAPI - 图6
009.1-ASP.NET WebAPI - 图7

3.3-WebAPI的返回值

009.1-ASP.NET WebAPI - 图8

  1. /// <summary>
  2. /// HttpResponseMessage类型
  3. /// 返回报文头、内容等等信息(控制相应的内容)
  4. /// </summary>
  5. /// <returns></returns>
  6. [HttpGet]
  7. [Route("Test3")]
  8. public HttpResponseMessage Test3() {
  9. HttpResponseMessage msg = new HttpResponseMessage();
  10. msg.Content =new StringContent( "报文体");
  11. msg.Headers.Add("Haha", "这是请求头体");
  12. msg.StatusCode = System.Net.HttpStatusCode.OK;
  13. msg.Headers.Age = TimeSpan.FromDays(3);
  14. return msg;
  15. }

3.4-通过自定义路由处理API多版本

009.1-ASP.NET WebAPI - 图9
009.1-ASP.NET WebAPI - 图10
009.1-ASP.NET WebAPI - 图11

3.5-通过ControllerSelector实现多版本(配置路由规则)

(1)创建2个版本控制器
009.1-ASP.NET WebAPI - 图12
(2)在【WebApiConfig】的Register中,添加1个路由规则,并替换IHttpControllerSelector

  1. config.Routes.MapHttpRoute(
  2. name: "DefaultApiV1",
  3. routeTemplate: "api/v1/{controller}/{id}",
  4. defaults: new { id = RouteParameter.Optional }
  5. );
  6. //添加一个路由规则
  7. config.Routes.MapHttpRoute(
  8. name: "DefaultApiV2",
  9. routeTemplate: "api/v2/{controller}/{id}",
  10. defaults: new { id = RouteParameter.Optional }
  11. );
  12. //替换
  13. config.Services.Replace(typeof(IHttpControllerSelector), new VersionControllerSelector(config));

(3)VersionControllerSelector.cs代码如下:

  1. namespace Demo
  2. {
  3. /// <summary>
  4. /// 用来控制API版本
  5. /// 需要继承自DefaultHttpControllerSelector
  6. /// </summary>
  7. public class VersionControllerSelector : DefaultHttpControllerSelector
  8. {
  9. private readonly HttpConfiguration _config;
  10. private IDictionary<string, HttpControllerDescriptor> _ctlMapping;
  11. public VersionControllerSelector(HttpConfiguration config) : base(config)
  12. {
  13. this._config = config;
  14. }
  15. public override IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
  16. {
  17. Dictionary<string, HttpControllerDescriptor> dict = new Dictionary<string, HttpControllerDescriptor>();
  18. //加载所有程序集,然后遍历
  19. foreach (var asm in _config.Services.GetAssembliesResolver().GetAssemblies())
  20. {
  21. //获得程序集所有的类,并且该类不是抽象类,并且继承自ApiController
  22. var controllerTypes = asm.GetTypes().Where(u => u.IsAbstract == false && typeof(ApiController).IsAssignableFrom(u));
  23. //遍历并生成名字
  24. foreach (var ctrlType in controllerTypes)
  25. {
  26. string ctrolTypeNS = ctrlType.Namespace;//获取命名空间名称
  27. var match = Regex.Match(ctrolTypeNS, @"\.v(\d)");//获得需要的名称
  28. if (!match.Success)
  29. {
  30. continue;
  31. }
  32. string verNum = match.Groups[1].Value;//拿到版本号1提取出来
  33. string ctrlTypeName = ctrlType.Name;//拿到类名(PersonController)
  34. //拿到匹配的类型
  35. var matchController = Regex.Match(ctrlTypeName, @"^(.+)Controller$");
  36. if (!matchController.Success)
  37. {
  38. continue;
  39. }
  40. string ctrlName = matchController.Groups[1].Value;//得到合法的PersonController
  41. string key = ctrlName + "v" + verNum;
  42. dict[key] = new HttpControllerDescriptor(_config, ctrlName,ctrlType);
  43. }
  44. }
  45. _ctlMapping = dict;
  46. return dict;
  47. }
  48. public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
  49. {
  50. //拿到controller
  51. string controller =(string)request.GetRouteData().Values["controller"];
  52. if (_ctlMapping == null) {
  53. //调用之前的方法拿到,key/value
  54. _ctlMapping = GetControllerMapping();
  55. }
  56. // /api/v1/person
  57. var matchVer = Regex.Match(request.RequestUri.PathAndQuery, @"/v(\d+)/");
  58. if (!matchVer.Success) {
  59. //我处理不了,让父类处理
  60. return base.SelectController(request);
  61. }
  62. string verNum = matchVer.Groups[1].Value;//2
  63. string key = controller + "v" + verNum;
  64. if (_ctlMapping.ContainsKey(key))
  65. {
  66. return _ctlMapping[key];
  67. }
  68. else {
  69. //我处理不了,让父类处理
  70. return base.SelectController(request);
  71. }
  72. }
  73. }
  74. }

3.6-WebAPI中Filter-简单判断是否授权

(1)新建一个类。
009.1-ASP.NET WebAPI - 图13
(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的异常处理

//系统错误
009.1-ASP.NET WebAPI - 图14
//业务错误
009.1-ASP.NET WebAPI - 图15

009.1-ASP.NET WebAPI - 图16

3.8-接口的安全性问题

009.1-ASP.NET WebAPI - 图17
009.1-ASP.NET WebAPI - 图18
009.1-ASP.NET WebAPI - 图19

3.9-JWT介绍

009.1-ASP.NET WebAPI - 图20

3.10-接口安全传输

009.1-ASP.NET WebAPI - 图21

3.11-项目:用户中心OpenAPI

009.1-ASP.NET WebAPI - 图22
009.1-ASP.NET WebAPI - 图23
//T_UserGroups(用户组表)
009.1-ASP.NET WebAPI - 图24
009.1-ASP.NET WebAPI - 图25
009.1-ASP.NET WebAPI - 图26

3.12-接口服务器写好之后的工作

(1)发布到IIS上
(2)写接口文档(例子):
009.1-ASP.NET WebAPI - 图27

四、WebAPI(.NET Core)

4.1-WebAPI在Core和EntityFramework区别?

009.1-ASP.NET WebAPI - 图28
上一篇

008.1-在.NET Core Web API中应用Swagger

下一篇

009.2-WebAPI2项目/跨域/JWT身份验证