实现服务层与api层共用,也就表明Service层就是api层。

  • 关键类和接口

    • System.Web.Http.Dispatcher.DefaultHttpControllerSelector

    webpai选择控制器的默认实现,可以重写SelectController方法

    • System.Web.Http.Controllers.ApiControllerActionSelector

    webapi选择指定控制器下的action的默认实现,可以重写SelectAction方法。

    • System.Web.Http.ApiController

    api控制器的基类,继承于此的类都可以成为Api控制器

  • 类和接口关系图 api自定义扩展实现

api注册流程

如果实现Servie层的Controller。

  • 所有服务类都需要继承于ApiController类,让服务类拥有控制器的特性 ApiServier类代码(继承ApiController此可,设置服务基类用于后期扩展):
public class ApiService:System.Web.Http.ApiController
{
}

TestServer类代码:

public class TestService:ApiService
{
public string Get()
{
return "Get-Test";
}
}

实现服务类,且具有ApiController的能力

    • 实现ServiceContainer类,实现服务类的缓存,并用于Controller的选择类,获取服务类代码如下:
private void Init()
{
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var ls = assembly.GetTypes().Where(x => typeof(Services.ApiService).IsAssignableFrom(x));
foreach(var item in ls)
{
_apis.Add(item.FullName, item);
}
}
    • 重写api选择controller类代码:
public class CustomSelectController:System.Web.Http.Dispatcher.DefaultHttpControllerSelector
{
public CustomSelectController(System.Web.Http.HttpConfiguration config) : base(config)
{ } public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
var routeData = request.GetRouteData().Values;
foreach( var route in routeData)
{
if(route.Key == "controller")
{
//找controller
var controllerType = ServicesContainer.CreateInstance().Apis
.Where(x => x.Key.ToLower().IndexOf(route.Value.ToString() + "service") > ).FirstOrDefault();
if (controllerType.Value!=null)
{
return new DyControllerDescriptor(request.GetConfiguration(), controllerType.Value);
}
}
} return base.SelectController(request);
}
}

注意:

  1. 选择Controller类必须有一个参数的构造函数,构造函数传入为httpConfiguration类
  2. 重写SelectController方法,实现从ServiceContainer中获取ApiService实现类
  3. 重写ActionSelector类
public class CustomActionActivator:System.Web.Http.Controllers.ApiControllerActionSelector
{
public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
{
if (!(controllerContext.ControllerDescriptor is DyControllerDescriptor))
{
return base.SelectAction(controllerContext);
} var realType = controllerContext.ControllerDescriptor as DyControllerDescriptor; Type[] types = new Type[];
System.Reflection.MethodInfo methodInfo = realType.ControllerInfo.GetMethod("Get",
types); return new DyActionDescriptor(controllerContext.Configuration, controllerContext.ControllerDescriptor, methodInfo);
}
}
  • 注意:

    1. 此类不重写也可以实现ApiService类的执行,此类主要是处理在Action执行前一个些额外操作。
    2. 从中我们也可以看出Action的执行也是需要MethodInfo这个类的实例。
  • Global.cs中注入Api路由时,必须在Mvc注入路由之前

protected void Application_Start()
{
common.ServicesContainer.CreateInstance(); AreaRegistration.RegisterAllAreas(); //必须放在RouteConfig.RegisterRoutes前面
GlobalConfiguration.Configure((config) =>
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
});
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles); GlobalConfiguration.Configuration.Services.Replace(typeof(System.Web.Http.Dispatcher.IHttpControllerSelector),
new common.CustomSelectController(GlobalConfiguration.Configuration));
GlobalConfiguration.Configuration.Services.Replace(typeof(System.Web.Http.Controllers.IHttpActionSelector), new common.CustomActionActivator());
}

运行结果:

.Net WebApi 初探的更多相关文章

  1. ASP.NET MVC学习系列(一)-WebAPI初探

    由于即将要接手的新项目计划用ASP.NET MVC3来开发,所以最近一段时间一直在看相关的书或文章.因为之前在大学里也曾学习过MVC2开发,也做过几个简单的MVC2的小型测试项目,不过在后来工作以后主 ...

  2. asp.net webapi初探(一)

    本人对webapi尚没有深入研究,初次接触发现了在数据请求时的几点现象. 先切入代码 1.如果action中开头带有Get默认就是get方式,不带Get默认就是post方式 public string ...

  3. WebAPI初探

    由于即将要接手的新项目计划用ASP.NET MVC3来开发,所以最近一段时间一直在看相关的书或文章.因为之前在大学里也曾学习过MVC2开发,也做过几个简单的MVC2的小型测试项目,不过在后来工作以后主 ...

  4. .net core WebAPI 初探及连接MySQL

    1. 前言 笔者最近跟着微软官方文档学习.net core WebAPI,但发现其对 WebAPI 连接数据库.读取数据库方面讲得不够细致明了.写此文的目的,即实现 .net core WebAPI ...

  5. WebApi初探之路由配置

    本文介绍了ASP.NET Web API路由HTTP请求控制器. 如果你熟悉ASP.NET MVC,Web API路由是和MVC路由非常相似的.主要差别是Web API使用HTTP方法而不是URI路径 ...

  6. ASP.NET MVC学习系列 WebAPI初探

    转自http://www.cnblogs.com/babycool/p/3922738.html 一.无参数Get请求 一般的get请求我们可以使用jquery提供的$.get() 或者$.ajax( ...

  7. WebApi初探之基本操作(CRUD)

    public class ProductsController : ApiController { static List<Product> products = new List< ...

  8. ASP.NET MVC学习系列(二)-WebAPI请求

    继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理. 这里我使用Jquery 来发起异步请求实现 ...

  9. ASP.NET MVC学习系列(二)-WebAPI请求(转)

    转自:http://www.cnblogs.com/babycool/p/3922738.html 继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的g ...

随机推荐

  1. IIS+Tomcat功能iis端口2

    之前写过IIS桥接Tomcat是通过isapi_redirect.dll,组件方式实现共用端口的,但是在Windows2012服务器 iis8.0版本中,配置完成后没有效果,比较抓狂,分析发现如下信息 ...

  2. python 字典、列表、字符串 之间的转换

    1.列表与字符串转换 1)列表转字符串: 将列表中的内容拼接成一个字符串 将列表中的值转成字符串 2)字符串转列表: 用eval转换 将字符串每个字符转成列表中的值 将字符串按分割成列表 2.列表与字 ...

  3. Vue-Router嵌套路由

    1:查看router-view所对应的位置,是属于顶级出口还是存在于某个组件当中 2:当router-view存在于某个组件当中时 const User = { template: ` <div ...

  4. itunes 备份导致C盘空间不足问题解决办法

    首先,itunes备份的默认路径是 C:\users\你的用户名\Appdata\Roaming\Apple computer 备份的主要存放文件在C:\Users\David_lu\AppData\ ...

  5. 关于阿里ICON矢量图(SVG)上传问题.

    注意点: 1. 存储为svg格式(建议使用存储为svg,不要使用导出为svg)2. 图像位置:链接(注意哦,不要点嵌入和保留编辑功能)---确定3. AI里面选中图形,点对象-路径-轮廓化描边 软件编 ...

  6. P2649 - 【NOIP2017】列队

    Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m 名学生,方阵的行数为 ...

  7. vue 格式化银行卡(信用卡)每4位一个符号隔断

    问题 在做银行卡输入框时有一个需求如题,这里举例用-隔断 调查 查看了很多大公司网站的银行卡输入,发现还有有很多缺陷的: 有的是在中间删除,光标会跳到最后: 有的是能删除掉中间隔断符的: 等等,逻辑感 ...

  8. php GD库快速消耗CPU资源漏洞 CVE-2018-5711测试

    漏洞说明: 用一张GIF图片就可导致服务器发生崩溃直至宕机,在现实中非常容易利用. 影响版本: PHP 5 < 5.6.33 PHP 7.0 < 7.0.27 PHP 7.1 < 7 ...

  9. LeetCode 31 Next Permutation / 60 Permutation Sequence [Permutation]

    LeetCode 31 Next Permutation / 60 Permutation Sequence [Permutation] <c++> LeetCode 31 Next Pe ...

  10. 《SpringMVC从入门到放肆》九、SpringMVC注解式开发(简单参数接收)

    上一篇我们学习了注解式开发的配置方式并写了一个小Demo跑起来.今天我们来学习注解开发的参数接收.处理器方法中的常用参数有五类,这些参数会在系统调用时由系统自动赋值,即程序员可以在方法中直接使用.具体 ...