Web API的参数、多版本和Filter
一、关于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的更多相关文章
- asp.net web api [FromBody]参数
Using jQuery to POST [FromBody] parameters to Web API 时间2013-04-04 00:28:17 Encosia原文 http://encosia ...
- ASP.NET Web API 通过参数控制返回类型(JSON|XML)
一个很实用的技巧,可以在访问web api服务的时候指定返回数据的格式类型,比如 json 或者 xml. 因为 web api 默认返回的是XML格式,但是现在json 比较流行,同时网上也有其他的 ...
- Web Api 返回参数,实现统一标准化!
string camelCaseObj = JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.None, new JsonSer ...
- Web API系列(二)接口安全和参数校验
以前简单介绍过web api 的设计,但是还是有很多朋友问我,如何合理的设计和实现web api.比如,接口安全,异常处理,统一数据返回等问题.所以有必要系统的总结总结 web api 的设计和实现. ...
- 基于.Net Framework 4.0 Web API开发(2):ASP.NET Web APIs 参数传递方式详解
概述: ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.调用API过程中参数的传递是必须的,本节就来谈谈 ...
- Html网页使用jQuery传递参数并获取Web API的数据
昨天Insus.NET有开始学习Web API,<ASP.NET MVC的Web Api的实练>http://www.cnblogs.com/insus/p/4334316.html .其 ...
- 细说 Web API参数绑定和模型绑定
今天跟大家分享下在Asp.NET Web API中Controller是如何解析从客户端传递过来的数据,然后赋值给Controller的参数的,也就是参数绑定和模型绑定. Web API参数绑定就是简 ...
- .NET Core WEB API中接口参数的模型绑定的理解
在.NET Core WEB API中参数的模型绑定方式有以下表格中的几种: 微软官方文档说明地址:https://docs.microsoft.com/zh-cn/aspnet/core/web-a ...
- Web API(四):Web API参数绑定
在这篇文章中,我们将学习Web API如何将HTTP请求数据绑定到一个操作方法的参数中. 操作方法在Web API控制器中可以有一个或多个不同类型的参数.它可以是基本数据类型或复杂类型.Web API ...
随机推荐
- 影响 POST 请求文件上传失败的几个环节的配置(php + nginx)
写在前面 最近写一个 php 接口,接受上传的文件,发现文件只要超过 5m 以上就会无响应失败,最后发现是 shadowsocks 的 timeout 设置问题(我全程开了全局的 VPN),但一开始并 ...
- Caffe 使用记录(五):math_functions 分析
本文转载自 Caffe源码(一):math_functions 分析 math_function 定义了caffe 中用到的一些矩阵操作和数值计算的一些函数,这里以float类型为例做简单的分析 1. ...
- numpy中pad函数的常用方法
一.参数解释 ndarray = numpy.pad(array, pad_width, mode, **kwargs) array为要填补的数组 pad_width是在各维度的各个方向上想要填补的长 ...
- Shell脚本中实现自动补全功能
对于Linuxer来说,自动补全是再熟悉不过的一个功能了.当你在命令行敲下部分的命令时,肯定会本能地按下Tab键补全完整的命令,当然除了命令补全之外,还有文件名补全. Bash-completion ...
- 关于jQuery的一些东西
1.jQuery的选择器学习 基本选择器 id选择器 $("#id名") 返回的是存储了指定的HTML元素对象的数组 标签 ...
- Java:类与对象概念
什么是类? 怎样定义一个类? 什么是对象,类和对象之间是什么关系,怎样创建一个对象? 对象引用和对象在内存中是如何分配的? 什么是类? 1. 类是具有相同的属性和功能的事物的抽象的集合,在面向对象 ...
- Docker容器绑定外部IP和端口
Docker允许通过外部访问容器或者容器之间互联的方式来提供网络服务. 以下操作通过myfirstapp镜像模拟,如何制作myfirstapp镜像请点击此处. 1.外部访问容器容器启动之后,容器中可以 ...
- Http怎么处理长连接
http协议中有和keep alive特性,这个在http1.1中有, 可以保持浏览器和服务器之间保持着长连接,http本身是无连接的协议, 通过tcp实现数据的传输,处理长连接要注意什么时候数据服务 ...
- Docker启动出现"No space left on device" 或者 docker日志太多导致磁盘占满问题
机房有一台服务器上面部署了多个docker容器, 并且每个docker容器都往stderr中源源不断的输出日志,导致磁盘被占满了.Docker容器在启动/重启的时候会往/var/lib/docker中 ...
- Python sqlalchemy的基本使用
示例代码 from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base fr ...