WebApi学习纪要

WebApi介绍

  • 微软的web api是完全基于RESTful标准的,完全不同于之前的(同是SOAP协议的)wcf和webService;
  • RESTful是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义,REST:Representational State Transfer(表象层状态转变),难懂!

特性路由

  • 将RouteAttribute或自定义继承自RouteAttribute的特性类标记在控制器或ACTION上,同时指定路由Url字符串,从而实现路由映射,相比之前的通过Routes.Add或Routes.MapHttpRoute来讲,更加灵活与直观,若要使用特性路由功能需要先在WebApiConfig.Register注册:config.MapHttpAttributeRoutes();或者在Application_Start里注册GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
1.基本路由映射:[Route("api/Values")]=>http://localhost:34732/api/values
2.路由映射到参数:[Route("api/Values/{id}")]=>http://localhost:34732/api/values/11
3.多重特性路由:[Route("api/Values/{value1}/{value2}")] [Route("api/Demo/{value2}/{value1}")]
4.缺省(默认)参数路由:[Route("api/Values/option/{key}/{value?}")]=>http://localhost:34732/api/Values/option/a
4.缺省(默认)参数路由:[Route("api/Values/option/{key}/{value=test}")]=>http://localhost:34732/api/Values/option/a/api
5.参数约束路由:[Route("api/Values/constraint/{id:range(1,10)}")]=>http://localhost:34732/api/Values/constraint/10

参数约束使用方法
参数约束使用方法

  • 也可以修改路由匹配规则,按mvc方法匹配路由(有action匹配);

好的api设计要点

  • URI、查询参数、HTTP方法、响应数据格式、出错信息、版本管理等:参考来源:如何设计出优美的Web API?
    • URI
    • 简短不冗余
      • 反例:http://api.example.com/service/api/users
      • 正例:http://api.example.com/users
    • 容易读懂的URI,不要随意采用缩写,x,y
      • 反例:http://api.example.com/x/y
    • 不要大小写混用的URI
    • 命名存在可预见的规律,改变最后的ID就可以访问其他商品的信息
      • 正例:http://api.example.com/v1/items/123456
    • 不会暴露服务端架构的URI
      • 反例:http://api.example.com/cgi-bin/get_user.php?user=100
    • 命名,参数规则统一的URI,比如要么采用查询参数或者要么采用了路径参数
      • 查询参数:http://api.example.com/friends?id=100,如果该属性可以省略,那么它就是适合作为查询参数
      • 路径参数:http://api.example.com/friends/100,如果该属性信息可以唯一定位资源,那么它就适合作为路径构成元素
    • URI最好由名词组成
    • 不使用空格及需要编码的字符,例如在URI中使用中文等
    • 查询参数
    • per-page与page风格:http://api.example.com/friends?per-page=50&page=3
    • limit与offset风格:http://api.example.com/friends?limit=50&offset=100
    • 完全符合,过滤参数的名称通常为属性名:http://api.example.com/v1/users?name=ken
    • 全文搜索,查询结果任意属性部分包含过滤参数的取值,那过滤参数的名称通常为“q”:http://api.example.com/v1/users?q=ken
    • HTTP方法,表示对资源的操作方法:
      • GET,获取资源
      • POST,新增资源
      • PUT,更新已有资源
      • DELETE,删除资源
      • PATCH,更新部分资源
      • HEAD,获取资源的元信息
    • 出错信息http状态码
      • 1XX:消息
        • 100 Continue,如post请求分2次,第1次建立连接,服务器返回100,客户端将数据post到服务器
      • 2XX:成功
        • 200 OK,对应http方法:get、put、patch返回
        • 201 Created,对应http方法:post
        • 204 No Content,对应http方法:delete
      • 3XX:重定向
        • 304 Not Modified
      • 4XX:客户端原因引起的错误
        • 400 Bad Request,请求数据校验错误
        • 401 Unauthorized账户验证错误
        • 403 Forbidden权限不足
        • 404 Not Found找不到资源
      • 5XX:服务器端原因引起的错误
        • 500 Internal Server Error服务器端的源代码出现错误
        • 502 Bad Gateway
        • 503 Service Unavailable服务器维护或者过载
        • 504 Gateway Timeout
    • 版本管理
    • 在URI中嵌入版本编号,示例:http://api.linkedin.com/v1/people
    • 在查询字符串里加入版本信息,示例:http://api.example.com/users/123?v=2
    • 通过媒体类型来指定版本信息,Accept: application/vnd.github.v3+json;Content-Type: application/vnd.github.v3+json

常用特性、过滤器应用

  • 过滤器是利用AOP实现的;
  • 权限特性AuthorizeAttribute,新增一个类,继承AuthorizeAttribute,重写OnAuthorization虚方法,然后在控制器或方法上新增此特性,相应的有个AllowAnonymousAttribute特性,可以避免权限验证;
//新增一个类,继承`AuthorizeAttribute`
public class MyBasicAuthorizeAttribute : AuthorizeAttribute
{
	//有 AllowAnonymousAttribute 特性的,无需进行权限验证
	if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != 0
	|| actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != 0)
	{
	base.OnAuthorization(actionContext);//执行真实逻辑
	} 
	else 
	if(请求头里有Ticket或者cookie里有Ticket,进行用户验证逻辑)
	{
		base.IsAuthorized(actionContext);	//如果成功,执行真实逻辑
	}
	else 
	{
		this.HandleUnauthorizedRequest(actionContext);//没有权限
	}
}
  • 异常处理特性ExceptionFilterAttribute,同样新增一个类,继承ExceptionFilterAttribute,重写OnException虚方法,因为是异常处理,建议全局生效,故在WebApiConfig.Register里注册(非FilterConfig.RegisterGlobalFilters(),这个是针对mvc的),而不是只修饰部分类,另外不能捕获控制器实例化和路径错误的异常,如果要捕获,则需继承ExceptionHandler类而不是ExceptionFilterAttribute
	//异常过滤器
  public class MyExceptionAttribute : ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext actionExecutedContext)
        {
        	
        }
    }    
	//在WebApiConfig.Register里注册
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            //异常处理注册,全局生效
            config.Filters.Add(new MyExceptionAttribute());
            // Web API 配置和服务
            // Web API 路由
         }
     }
  • 方法过滤特性,继承ActionFilterAttribute类,重写OnActionExecuting(方法执行前)和OnActionExecuted(方法执行后),比如执行方法后,在response里加入允许跨域的响应头信息actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
 public class CustomActionFilterAttribute : ActionFilterAttribute
	{
	      /// <summary>
        /// 方法执行前
        /// </summary>
        /// <param name="actionContext"></param>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
        	//处理逻辑
        }
      /// <summary>
        /// 方法执行后
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
        	//处理逻辑
        	//允许跨域
        	actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        	base.OnActionExecuted(actionExecutedContext);
        }
	}
原文地址:https://www.cnblogs.com/zoulei0718/p/14315577.html