翼度科技»论坛 编程开发 .net 查看内容

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

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
一、什么是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和是使用异步方式调用
  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. }
复制代码


3.2-WebAPI的参数







3.3-WebAPI的返回值

  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多版本





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

(1)创建2个版本控制器

(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.            
  57.             // /api/v1/person
  58.             var matchVer = Regex.Match(request.RequestUri.PathAndQuery, @"/v(\d+)/");
  59.             if (!matchVer.Success) {
  60.                 //我处理不了,让父类处理
  61.                 return base.SelectController(request);
  62.             }
  63.             string verNum = matchVer.Groups[1].Value;//2
  64.             string key = controller + "v" + verNum;
  65.             if (_ctlMapping.ContainsKey(key))
  66.             {
  67.                 return _ctlMapping[key];
  68.             }
  69.             else {
  70.                 //我处理不了,让父类处理
  71.                 return base.SelectController(request);
  72.             }
  73.         }
  74.     }
  75. }
复制代码
3.6-WebAPI中Filter-简单判断是否授权

(1)新建一个类。

(2)类的代码如下:
  1. namespace Demo.Filter
  2. {
  3.     public class MyAuthorFilter : IAuthorizationFilter
  4.     {
  5.         public bool AllowMultiple => true;
  6.         public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
  7.         {
  8.             IEnumerable<string> userNames;
  9.             if (!actionContext.Request.Headers.TryGetValues("UserName", out userNames)){
  10.                 //返回未授权状态码
  11.                 return new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
  12.             };
  13.             string userName = userNames.First();
  14.             if (userName == "admin")
  15.             {
  16.                 return await continuation();
  17.             }
  18.             else {
  19.                 //返回未授权状态码
  20.                 return new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
  21.             }
  22.         }
  23.     }
  24. }
复制代码
(3)在【WebApiConfig.cs】的Register方法进行注册自定义的Filter。
  1. //注册自己写的Filter
  2. config.Filters.Add(new MyAuthorFilter());
复制代码
3.7-WebAPI的异常处理

系统错误:

业务错误:



3.8-接口的安全性问题






3.9-JWT介绍



3.10-接口安全传输



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

来源:https://www.cnblogs.com/kimiliucn/archive/2023/08/05/17607795.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具