愛在花開的季節 发表于 2023-8-7 18:07:32

探索ASP.NET Framework WebAPI的简介与应用

一、什么是WebAPI?

1.1-什么是WebAPI?

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

1.2-WebAPI的特点?


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

二、什么是Restful?

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

https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823648-983089537.png

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;
      }

    }
}https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823726-795897543.png

3.2-WebAPI的参数

https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823686-1564344049.png
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823658-1436703381.png
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823850-1273421500.png
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823751-1583771019.png
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823653-1701707351.png

3.3-WebAPI的返回值

https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823852-1779885542.png
      /// <summary>
      /// HttpResponseMessage类型
      /// 返回报文头、内容等等信息(控制相应的内容)
      /// </summary>
      /// <returns></returns>
      
      
      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多版本

https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823890-215568445.png
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823681-1217831261.png
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823861-1556830957.png

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

(1)创建2个版本控制器
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823718-14003016.png
(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.Value;//拿到版本号1提取出来
                  string ctrlTypeName = ctrlType.Name;//拿到类名(PersonController)
                   //拿到匹配的类型
                  var matchController = Regex.Match(ctrlTypeName, @"^(.+)Controller$");
                  if (!matchController.Success)
                  {
                        continue;
                  }

                  string ctrlName = matchController.Groups.Value;//得到合法的PersonController
                  string key = ctrlName + "v" + verNum;
                  dict = 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.Value;//2
            string key = controller + "v" + verNum;
            if (_ctlMapping.ContainsKey(key))
            {
                return _ctlMapping;
            }
            else {
                //我处理不了,让父类处理
                return base.SelectController(request);
            }
      }

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

(1)新建一个类。
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823586-414267964.png
(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的异常处理

系统错误:
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823891-329441933.png
业务错误:
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823856-1305075896.png
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823754-1987749263.png

3.8-接口的安全性问题

https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823950-1464772037.png
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823859-107191547.png
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823627-121708457.png
https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823890-1856017529.png

3.9-JWT介绍

https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823890-401891615.png

3.10-接口安全传输

https://img2023.cnblogs.com/blog/3240243/202308/3240243-20230805123823769-742389520.png

原文链接:https://www.cnblogs.com/kimiliucn/p/17607795.html

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 探索ASP.NET Framework WebAPI的简介与应用