一、关于API的参数
a) Web API在WebApiConfig.cs中配置了路由模板,默认为"api/{controller}/{id}",这与MVC路由模板的区别在于没有{action},会根据请求方式来找到对应的方法,只要一个Action标注了[HttpGet],那么不管Action的名称如何,Get请求都会被路由到这个Action。
b)如果有GET请求为http:/***/api/Controller?user="u1"&pwd="p1",按照默认的路由配置,有效的GET方法可以是public string Login(string user, string pwd)。也可以使用[FromUri],但GET方法改为public string Login([FromUri]LoginModel model) ,将参数封装为Model并添加FromUri,FromUri只能标注一个参数,经试验也可以在使用FromUri的同时使用多个参数。
c)对于Post、Put请求,也可以像Get请求那样写在URI中,但参数比较多时最好封装起来,通过Request Body传递,同时在参数上标记[FromBody]。同样的这个标记也只能使用一次。对于POST方法public string Login2(int i,[FromBody]LoginModel model,string us) 来说,请求是在url中传递的i和us参数的顺序不限。
d)也可以模仿MVC的路由模板,配置为"api/{controller}/{action}/{id}",这样使用方式更加直观,但无法根据请求方式自动对应,且不符合REST风格。
二、WebAPI的多版本管理
有时在升级API的同时需要保留旧版本的API,不同的URL请求不同版本的API。这时可以将不同版本的API部署在不同的服务器或域名。或者放在同一个项目中,然后使用IHttpControllerSelector来区分不同的版本,代码如下:
public class VersionControllerSelector : DefaultHttpControllerSelector {
  private HttpConfiguration _config;
  public VersionControllerSelector(HttpConfiguration configuration) : base(configuration) {
    _config = configuration;
  }
  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(t => !t.IsAbstract && typeof(ApiController).IsAssignableFrom(t)).ToArray();
      foreach (var ctrlType in controllerTypes) {
        //从namespace中提取版本号
        var match = Regex.Match(ctrlType.Namespace, @"_8._1_WebAPI.Controllers.v(\d+)");
        if (match.Success) {
          string verNum = match.Groups[1].Value;
          string ctrlName = Regex.Match(ctrlType.Name, "(.+)Controller").Groups[1].Value;
          string key = ctrlName + "v" + verNum;
          dict[key] = new HttpControllerDescriptor(_config, ctrlName, ctrlType);
        }
      }
    }
    return dict;
  }

public override HttpControllerDescriptor SelectController(HttpRequestMessage request) {

var controllers = GetControllerMapping();
    //获取路由数据
    var routeData = request.GetRouteData();
    //从路由中获取当前Controller的名称
    var controllerName = (string)routeData.Values["controller"];
    //从url中获取版本号
    string verNum = Regex.Match(request.RequestUri.PathAndQuery, @"api/v(\d+)").Groups[1].Value;
    //从报文头获取版本号
    //string verNum = request.Headers.GetValues("ApiVersion").Single();
    string key = controllerName + "v" + verNum;
    return controllers.ContainsKey(key) ? controllers[key] : null;
  }
}

然后在WebApiConfig中配置两个路由模板:
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 }

最后将IHttpControllerSelector用写好的VersionControllerSelector替换就可以了
config.Services.Replace(typeof(IHttpControllerSelector), new VersionControllerSelector(config));

三、Filter
和MVC的Filter的写法基本类似,作用也一致,提供AOP功能。但人家直接按照异步形式写的。
a) IAuthorizationFilter的基本使用
public class MyAuthFilter : IAuthorizationFilter {
  public bool AllowMultiple => true;

public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) {
    IEnumerable<string> values;
    if (actionContext.Request.Headers.TryGetValues("UserName", out values)) {
      var userName = values.FirstOrDefault();
      if (!userName.Equals("admin")) {
        return new HttpResponseMessage(HttpStatusCode.Unauthorized);
      }
    }
    else {
      return new HttpResponseMessage(HttpStatusCode.Unauthorized);
    }
    return await continuation();
  }
}
b) IExceptionFilter的基本使用
public class ExceptionFilter : IExceptionFilter {
  public bool AllowMultiple => false;

public async Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) {
    using (StreamWriter writer = File.AppendText("d:/err.txt")) {
      await writer.WriteLineAsync(actionExecutedContext.Exception.ToString());
    }
  }
}

学习资料:如鹏网.net提高班http://www.rupeng.com/News/10/4603.shtml

Web API的参数、多版本和Filter的更多相关文章

  1. asp.net web api [FromBody]参数

    Using jQuery to POST [FromBody] parameters to Web API 时间2013-04-04 00:28:17 Encosia原文 http://encosia ...

  2. ASP.NET Web API 通过参数控制返回类型(JSON|XML)

    一个很实用的技巧,可以在访问web api服务的时候指定返回数据的格式类型,比如 json 或者 xml. 因为 web api 默认返回的是XML格式,但是现在json 比较流行,同时网上也有其他的 ...

  3. Web Api 返回参数,实现统一标准化!

    string camelCaseObj = JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.None, new JsonSer ...

  4. Web API系列(二)接口安全和参数校验

    以前简单介绍过web api 的设计,但是还是有很多朋友问我,如何合理的设计和实现web api.比如,接口安全,异常处理,统一数据返回等问题.所以有必要系统的总结总结 web api 的设计和实现. ...

  5. 基于.Net Framework 4.0 Web API开发(2):ASP.NET Web APIs 参数传递方式详解

    概述:  ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.调用API过程中参数的传递是必须的,本节就来谈谈 ...

  6. Html网页使用jQuery传递参数并获取Web API的数据

    昨天Insus.NET有开始学习Web API,<ASP.NET MVC的Web Api的实练>http://www.cnblogs.com/insus/p/4334316.html .其 ...

  7. 细说 Web API参数绑定和模型绑定

    今天跟大家分享下在Asp.NET Web API中Controller是如何解析从客户端传递过来的数据,然后赋值给Controller的参数的,也就是参数绑定和模型绑定. Web API参数绑定就是简 ...

  8. .NET Core WEB API中接口参数的模型绑定的理解

    在.NET Core WEB API中参数的模型绑定方式有以下表格中的几种: 微软官方文档说明地址:https://docs.microsoft.com/zh-cn/aspnet/core/web-a ...

  9. Web API(四):Web API参数绑定

    在这篇文章中,我们将学习Web API如何将HTTP请求数据绑定到一个操作方法的参数中. 操作方法在Web API控制器中可以有一个或多个不同类型的参数.它可以是基本数据类型或复杂类型.Web API ...

随机推荐

  1. 《JavaScript面向对象编程指南》读书笔记①

    概述 JavaScript快忘完了,想看一本专业书拾遗,所以看了这本<JavaScript面向对象编程指南>. 个人觉得这本书讲的很透彻很易懂,一些原来有疑惑的地方在这本书里面豁然开朗,看 ...

  2. Shell - 简明Shell入门14 - 操作符(Operator)

    示例脚本及注释 #!/bin/bash echo "No code, just some comments." # ### 通配符 # * 代表任意(0个或多个)字符 # ? 代表 ...

  3. PHP使用Zend Opcache之优化加速和缓存清理总结

    简介 字节码缓存不是php的新特性,有很多独立性的扩展可以实现缓存,比如PHP Cache(APC),eAccelerator,ionCube和XCache等等.但是到目前为止,这些独立的扩展并没有集 ...

  4. 测试工具之Jmeter(创建一个简单测试用例)

    前面介绍了如何使用badboy录制jmeter脚本,以及如何导入脚本并进行测试 这里介绍下手动创建测试用例,主要步骤如下: 1.创建线程组 第一次打开Jmeter只有一个测试计划,右键“测试计划”选择 ...

  5. 从零开始学 Web 之 ES6(一)ES5严格模式

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  6. 在centos上使用yum安装rabbitmq-server

    rabbitmq及其依赖环境 rabbitmq安装之前需要安装socat,否则直接安装rabbitmq可能会报错 如果没有找到,则先安装epel源 yum -y install epel-releas ...

  7. Java并发编程笔记之StampedLock锁源码探究

    StampedLock是JUC并发包里面JDK1.8版本新增的一个锁,该锁提供了三种模式的读写控制,当调用获取锁的系列函数的时候,会返回一个long 型的变量,该变量被称为戳记(stamp),这个戳记 ...

  8. PHP 正则表达式资料

    正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串.将匹配的子串做替换或者从某个串中取出符合某个条件的子串等. 举例来说,正则表达式的一个 ...

  9. 深度学习论文翻译解析(一):YOLOv3: An Incremental Improvement

    论文标题: YOLOv3: An Incremental Improvement 论文作者: Joseph Redmon Ali Farhadi YOLO官网:YOLO: Real-Time Obje ...

  10. python的Web框架,中间件middleware及djangoAdmin

    简介 用于处理request和response的中间处理的函数,可以创建在项目中的任意位置,只要可以导入即可. 建议创建在APP目录下,方便管理. 函数范式与激活 中间件的范式: # 必须接受get_ ...