- WebApi 的说明
WebService--->WCF--->WebApi
RESTful架构风格:表现层的状态转化, 是一个接口的设计风格
资源:万物看成资源(主要Json),
统一接口:CRUD增删改查,跟HTTP Method对应
Create--Post Read--Get Update--Put/Patch Delete--Delete
URI:统一资源定位符,资源对应的唯一地址
无状态:基于Http协议, (登陆系统--查询工资--计算税收,有状态)
无状态的直接一个地址,就能拿到工资,就能得到税收
WebService---http协议,soap协议,只能IIS承载,入门简单,XML跨平台
WCF---集大成者,多种协议,多种宿主,整合了RPC。
RPC模式,都是调用方法的,
WebApi:RESTful,http协议 无状态 标准化操作 更轻量级,尤其是json,适合移动端
- WebApi运行规则
网站启动时执行Application_Start---给Routes增加地址规则---请求进来时--会经过路由匹配找到合适的《控制器》
那怎么找的Action(方法)?
1 根据HttpMethod找方法---用的方法名字开头,Get就是对应Get请求
2 如果名字不是Get开头,可以加上[HttpGet]
[HttpGet] public IEnumerableLGet(){ return new string[] { "value1", "value2" };}
3 按照参数找最吻合
api路由配置说明:
config.Routes.MapHttpRoute( name: "DefaultApi",//默认的api路由 routeTemplate: "api/{controller}/{id}",//正则规则,以api开头,第二个是控制器 第三个是参数 defaults: new { id = RouteParameter.Optional } );
- 路由特性
其实资源是这样定义的,不是一个学生,而可能是一个学校
可能是一个订单--多件商品,一次查询,订单-商品,数据之前嵌套关系很复杂还有个特性路由!可以单独订制1 config.MapHttpAttributeRoutes();2 标记特性 版本兼容---约束路由---默认值/可空路由---多数据//版本兼容 [Route("api/Values/{id}/V2")]public string GetV2(int id){ return "value V2";}
//约束路由 默认值/可空路由 [Route("api/Values/{id:int?}")]//可空 public string GetId(int id = 10)//Id查询 { return $"value {id}"; }
//多数据或多参数[Route("api/Values/{id}/Type/{typeid:int}")] public string GetType(int id,int typeid) { return $"value type {id}-{typeid}"; }
- IOC控制反转和依赖注入
控制器也要注入--完成容器和WebApi框架融合--实现IDependencyResolver,将容器放进去--初始化讲 config.DependencyResolver 换成自定义的Resolver
需要在nuget中引入Unity;
在nuget引用之后,单独引用Unity.Configuration;
如果有AOP扩展,还需要引用Unity.Interception.Configuration;
因为我们是用配置文件来做的配置;
配置文件内容Unity.Config:
Unity容器读取配置文件初始化
public class ContainerFactory { //Unity容器 //只需要读取一次配置文件和初始化一次 public static IUnityContainer BuildContainer() { return _Container; } private static IUnityContainer _Container = null; static ContainerFactory() { ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");//找配置文件的路径 Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName); _Container = new UnityContainer(); section.Configure(_Container, "WebApiContainer"); } }
完成容器和WebApi框架融合--实现IDependencyResolver ,将容器放进去
public class UnityDependencyResolver : IDependencyResolver { private IUnityContainer _UnityContainer = null; public UnityDependencyResolver(IUnityContainer container) { this._UnityContainer = container; } public IDependencyScope BeginScope() //作用域 { //每一个创建一个子容器,但只要读一次配置文件 return new UnityDependencyResolver(this._UnityContainer.CreateChildContainer()); } public void Dispose() //释放 { this._UnityContainer.Dispose(); } public object GetService(Type serviceType) { try { return this._UnityContainer.Resolve(serviceType); } catch (Exception ex) { return null; } } public IEnumerable
初始化将 config.DependencyResolver 换成自定义的Resolver
config.DependencyResolver = new UnityDependencyResolver(ContainerFactory.BuildContainer());
控制器中使用
public class IOCController : ApiController { private IUserService _UserService = null; public IOCController(IUserService userService) { this._UserService = userService; } public string Get(int id) { //IUserService service = new UserService(); //IUserService service = ContainerFactory.BuildContainer().Resolve(); return Newtonsoft.Json.JsonConvert.SerializeObject(this._UserService.Query(id)); } }