Web API使用记录系列(一)创建API项目与基本配置
本系列文章主要记录Web API使用过程中的一些个人总结,包括创建API项目、基础配置、ApiTestClient使用与HelpPage页面的优化、Owin与OAuth的使用等。
本节主要内容是API项目的创建和基本的配置
Aps.net Web API是构建Restful应用程序的.net框架,关于其相关介绍文档等请访问微软的 ASP.NET Web APIs
目录
项目创建
基本配置
路由模板配置
特性(属性)路由
过滤器
启动HelpPage页
返回值格式更改(json、禁用自引用等)
返回值日期格式
错误与解决方案
其它
一、创建项目
VS2017新建项目,选择Web下的Asp.NET Web应用程序
点击“确定”后在选择API应用,如果需要单元测试项目可以勾选“添加单元测试”,会在创建API项目的同时一起创建单元测试项目
点击确定,等待VS自动创建完成即可。创建完成后的项目结构基本跟Asp.NET MVC相似,但你会发现最明显的两个文件WebApiConfig.cs和ValueController.cs。
WebApiConfig.cs在项目的App_Start目录下,只有一个Register方法,这里面包含了Web API的配置、服务、路由等信息;
ValueController.cs在项目的Controllers目录下,是模板自带的一个Api接口示例,细心的你会发现它与MVC控制器的区别是,它继承自ApiController;
至此,VS为我们创建好了一个带有示例的API项目,现在可以运行项目,尝试调用示例中的接口。备注:运行项目后我们可以输入localhost:端口/help,进入帮助页面查看所有的api接口列表。
比如我们访问示例下的无参Get方法
我们可以看到接口返回了一个xml结构的数据,其中包含了接口中预置的value1和value2,有细心的会发现,你不是要调用的Get么,为啥路径是api/Values而不是api/Values/Get,别着急这在接下来的配置中讲到,这属于API的路由规则配置。
二、基本配置
接下来对创建的api项目进行一些配置修改。
1.路由模板格式修改(WebApiConfig文件)
我们修改原路由配置(api/{controller}/{id})如下
1 config.Routes.MapHttpRoute( 2 name: "DefaultApi", 3 routeTemplate: "api/{controller}/{action}", 4 defaults: new { id = RouteParameter.Optional } 5 );
这样修改后路由的匹配规则就变成了api/控制器名/方法名,刚才我们的访问Get方法就不能使用api/Values而需要使用api/Values/Get了。当然如果你的接口是需要写在Areas下的话,可以将routTemplate改为ap/{controller}/{action},或再添加一条路由规则
2.特性(属性)路由
特性路由的启用是在WebApiConfig的Register方法中添加config.MapHttpAttributeRoutes();即可,默认的是启用了该配置的。
之所以单独说一下是因为,使用特性路由的情况下WebApiConfig的注册只能使用GlobalConfiguration.Configure(WebApiConfig.Register),不能使用WebApiConfig.Register(GlobalConfiguration.Configuration)。
属性路由也是将客户端的请求映射到对应的action上,但相对于通过模板、http方法等来设置路由更加灵活,并且一些个性的需求使用模板、管理等很难实现。参考 JIM.WEN 的web api Route属性定义
3.过滤器
Web API的过滤器主要有三种AuthorizationFilterAttribute、ActionFilterAttribute、ExceptionFilterAttribute,根据你的运用创造力可以实现很多的自定义操作(骚操作~),网上相关的使用示例讲解蛮多的,就不写了,可参考 尘嚣之上的webapi的几种过滤器。
这里主要说一下ExceptionHandler和ExceptionLogger。为什么讲他们呢,是因为ExceptionFilterAttribute虽然可以定义全局异常处理,但是有一些异常它是不能处理的,例如:控制器构造函数的异常、消息处理程序异常、路由过程中的异常、序列化返回内容抛出的异常、其他过滤器的异常等。
定义两个类分别继承自ExceptionHandler和ExceptionLogger:
/// <summary> /// 自定义异常处理 /// </summary> public class CustomExceptionHandler : ExceptionHandler { public override void Handle(ExceptionHandlerContext context) { //可以处理一下统一的返回格式、自定义处理等 //content.Result } } /// <summary> /// 自定义异常日志 /// </summary> public class CustomExceptionLogger : ExceptionLogger { public override void Log(ExceptionLoggerContext context) { //可以处理下异常日志记录等 //context.Request.RequestUri--请求地址 //context.Request.Content--请求内容 //context.ExceptionContext.Exception--异常信息 } }
4.项目启动打开Help页
启动API项目后,需要手动敲入/Help才能进入帮助文档页面,操作不是很友好,我们可以通过修改路由来实现启动后直接进入help页,代码如下(App_Start--RouteConfig):
1 /// <summary> 2 /// 3 /// </summary> 4 /// <param name="routes"></param> 5 public static void RegisterRoutes(RouteCollection routes) 6 { 7 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 8 9 routes.MapRoute( 10 name: "Default", 11 url: "{controller}/{action}/{id}", 12 defaults: new { controller = "Help", action = "Index", id = UrlParameter.Optional }, 13 namespaces: new string[] { "SampleAPI.Areas.HelpPage.Controllers" } 14 ).DataTokens.Add("Area", "HelpPage"); 15 }
5.返回数据格式修改(返回json格式数据)
在WebApiConfig的Regiter中添加以下代码,即可
1 // Web API 配置和服务 2 3 //清除XML格式 4 config.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); 5 //JSON格式 6 config.Formatters.Add(new JsonMediaTypeFormatter());
再调用我们的Get方法,发现返回值已经是json格式的了
返回Json数据序列化时针对返回结果的child自引用循环,我们可以设置忽略,我们这里使用的序列化插件是Newtonsoft.json,在WebApiConfig中增加如下配置
1 var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First(); 2 //忽略对象的child自引用循环 3 config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
6.返回结果中日期的统一格式化处理
这里配置的是 “yyyy-MM-dd HH:mm:ss”格式,可根据自己的需要进行设置
1 config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter() 2 { 3 DateTimeFormat = "yyyy'-'MM'-'dd' 'HH':'mm':'ss" 4 });
三、错误与解决方案
1.“该对象尚未初始化。请确保在所有其他初始化代码后面的应用程序启动代码中调用 HttpConfiguration.EnsureInitialized()。”
或 “ValueFactory 尝试访问此实例的 Value 属性。”
原因:启用了特性路由但WebApiCofig的注册又使用了WebApiConfig.Register(GlobalConfiguration.Configuration)
解决方案:将WebApiCofig的注册方式改为GlobalConfiguration.Configure(WebApiConfig.Register)即可
附:两种注册方式的区别 stackoverflow
2.WebApi所有的接口访问全部404 找不到匹配的资源
原因:api路由注册放在了mvc路由的后边
解决方案:将GlobalConfiguration.Configure(WebApiConfig.Register)放到RouteConfig.RegisterRoutes(RouteTable.Routes)执行之前即可,别问我为什么,我也不明白这骚操作,😄
四、其它
没啥要说的,推荐 ‘懒得安分’的WebAPI系列文章,对测试工具、跨域、出入参、异常处理等讲的挺好,上链接 http://www.cnblogs.com/landeanfen/p/5210356.html
关于API项目的创建与配置,先记录这些,有用到的再补充,又不对的地方希望大家帮忙指正修改,感谢!