现有Momoda.Api项目,由于团队所有人在此项目下开发,导致耦合度太高,现从此接口项目中拆分出多个子项目从而避免对Momda.Api的改动导致“爆炸”
MVCApi的跨项目路由和MVC有解决方式有点不同
第一步:
首先在Momoda下创建域创建好之后把生成的YZCAreaRegistration文件移动到Areas目录下YZC目录外,然后排除YZC文件夹,像这样:
第二步:
创建一个新的MVCApi叫 YZC.WebAi,在资源管理器中用 YZC.WebAi文件夹下的内容替换掉Areas下的YZC域文件夹中的内容,并且只留下Controllers,Views和Models三个文件夹,其他的config和Global等都删除
第三步:
右键LYL解决方案添加现有项目在YZC域下找到工程文件 ( \LYL\Momoda.Api\Areas)
这样就把Momoda.Api下的YZC域给拆分出来,开发过程中只关注YZC.WebApi即可,目录结构如下图:
第四步:
更改YZCAreaRegistration域路由文件。
Api路由文件的更改是否和MVC跨域路由一样添加context.MapRoute方法的最后一个命名空间参数就能解决呢?答案当然没有那么简单。。。。。哈哈哈哈
我们现验证以下是否按照MVC跨项目路由的解决方案也同样适用于Api。
更改父API项目的域路由文件:
 public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"YZC_default",
"YZC/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "YZC.Controllers" }//添加域项目的控制层命名空间
);
}
在子api项目中添加controller:
 {
public class ChildrenController : ApiController
{
#region 跨项目路由测试
[HttpGet]
public string Test()
{
return "小良哥";
}
#endregion
}
}
浏览器中测试结果:
没有路由到,表明MVC域的处理和Api域的处理是不同的
解决方案:
在父ApiMomoda.Api下的App_Start中新增叫CustomHttpControllerSelector的类并且继承DefaultHttpControllerSelector
代码如下:
 /// <summary>
/// 自定义区域类
/// </summary>
public class CustomHttpControllerSelector: DefaultHttpControllerSelector
{
private const string NamespaceRouteVariableName = namespaceName";
//namespaceName之后要用到
//private const string AreaRouteVariableName = "area";
private readonly HttpConfiguration _configuration;
private readonly Lazy<ConcurrentDictionary<string, Type>> _apiControllerCache; public CustomHttpControllerSelector(HttpConfiguration configuration)
: base(configuration)
{
_configuration = configuration; _apiControllerCache = new Lazy<ConcurrentDictionary<string, Type>>(
new Func<ConcurrentDictionary<string, Type>>(InitializeApiControllerCache));
} private ConcurrentDictionary<string, Type> InitializeApiControllerCache()
{
IAssembliesResolver assembliesResolver = this._configuration.Services.GetAssembliesResolver();
var types = this._configuration.Services.GetHttpControllerTypeResolver()
.GetControllerTypes(assembliesResolver).ToDictionary(t => t.FullName, t => t); return new ConcurrentDictionary<string, Type>(types);
} public IEnumerable<string> GetControllerFullName(HttpRequestMessage request, string controllerName)
{
object namespaceName;
var data = request.GetRouteData();
IEnumerable<string> keys = _apiControllerCache.Value.ToDictionary<KeyValuePair<string, Type>, string, Type>(t => t.Key,
t => t.Value, StringComparer.OrdinalIgnoreCase).Keys.ToList(); if (!data.Values.TryGetValue(NamespaceRouteVariableName, out namespaceName))
{
return from k in keys
where k.EndsWith(string.Format(".{0}{1}", controllerName,
DefaultHttpControllerSelector.ControllerSuffix), StringComparison.OrdinalIgnoreCase)
select k;
} string[] namespaces = (string[])namespaceName;
return from n in namespaces
join k in keys on string.Format("{0}.{1}{2}", n, controllerName,
DefaultHttpControllerSelector.ControllerSuffix).ToLower() equals k.ToLower()
select k;
} public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
Type type;
if (request == null)
{
throw new ArgumentNullException("request");
} string controllerName = this.GetControllerName(request);
if (string.IsNullOrEmpty(controllerName))
{
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,
string.Format("No route providing a controller name was found to match request URI '{0}'",
new object[] { request.RequestUri })));
} IEnumerable<string> fullNames = GetControllerFullName(request, controllerName);
if (fullNames.Count() == )
{
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,
string.Format("No route providing a controller name was found to match request URI '{0}'",
new object[] { request.RequestUri })));
} if (!this._apiControllerCache.Value.TryGetValue(fullNames.First(), out type))
{
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,
string.Format("No route providing a controller name was found to match request URI '{0}'",
new object[] { request.RequestUri })));
} return new HttpControllerDescriptor(_configuration, controllerName, type);
}
}
更改父API项目的域路由文件为:
 namespace Momoda.Api
{
public class YZCAreaRegistration : AreaRegistration
{
public override string AreaName//域名称
{
get
{
return "YZC";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.Routes.MapHttpRoute(
name: this.AreaName + "_default",
routeTemplate: "api/" + this.AreaName + "/{controller}/{action}/{id}",
defaults: new
{
id = RouteParameter.Optional,
namespaceName = new string[] { string.Format("{0}.Controllers",this.AreaName) }
//namespaceName名称要CustomHttpControllerSelector中NamespaceRouteVariableName的值一致
}
);
}
}
}
这样就完成了吗?没有!!!必须把域YZC.WebApi生成路径设置为Momoda.Api的bin文件下
测试结果:
成功!
域名称可加可不加同样成功
17:57:11,嘿嘿,下班啦
 
 
 
 
 
 
 
 
 
 
 
 

MVC Api 的跨项目路由的更多相关文章

  1. MVC跨项目路由

    我们在实际应用开发中,经常遇到多人共同开发维护同一个项目情况,所以不免会出现其中一个人代码出现bug质量问题导致整个项目就原地“爆炸”的惨状.在之前公司经常遇到某个人忘记更新(我就做个此事[" ...

  2. ASP.NET MVC API 路由生成规则

    我们都知道调用ASP.NET MVC的某些API函数(诸如:Url.Action.RedirectToAction等)可以生成URL,ASP.NET MVC会根据调用API函数时传入的参数去匹配系统定 ...

  3. 初试ASP.NET Web API/MVC API(附Demo)

    写在前面 HTTP RESTful 创建Web API 调用Web API 运行截图及Demo下载 ASP.NET Web API是​​一个框架,可以很容易构建达成了广泛的HTTP服务客户端,包括浏览 ...

  4. ASP.NET Web API(MVC API)

    ASP.NET Web API是​​一个框架,可以很容易构建达成了广泛的HTTP服务客户端,包括浏览器和移动设备.是构建RESTful应用程序的理想平台的.NET框架. 上面是微软对Web API给出 ...

  5. Web API 解决跨域问题

    一.跨域问题的由来 同源策略:出于安全考虑,浏览器会限制脚本中发起的跨站请求,浏览器要求JavaScript或Cookie只能访问同域下的内容. 正是由于这个原因,我们不同项目之间的调用就会被浏览器阻 ...

  6. ASP.NET MVC 及 Areas 简单控制路由

    ASP.NET MVC中怎么去控制路由,这个想关的文章很多,我在这里就是自我总结一下,仅供参考. 1.我们新建一个项目,查看RouteConfig.cs,代码如下: public static voi ...

  7. ASP.NET MVC中设置跨域

    ASP.NET MVC中设置跨域 1.什么是跨域请求 js禁止向不是当前域名的网站发起一次ajax请求,即使成功respone了数据,但是你的js仍然会报错.这是JS的同源策略限制,JS控制的并不是我 ...

  8. js基础 js自执行函数、调用递归函数、圆括号运算符、函数声明的提升 js 布尔值 ASP.NET MVC中设置跨域

    js基础 目录 javascript基础 ESMAScript数据类型 DOM JS常用方法 回到顶部 javascript基础 常说的js包括三个部分:dom(文档document).bom(浏览器 ...

  9. ASP.NET CORE 1.0 MVC API 文档用 SWASHBUCKLE SWAGGER实现

    from:https://damienbod.com/2015/12/13/asp-net-5-mvc-6-api-documentation-using-swagger/ 代码生成工具: https ...

随机推荐

  1. java观察者模式

      像activeMQ等消息队列中,我们经常会使用发布订阅模式,但是你有没有想过,客户端时如何及时得到订阅的主题的信息?其实就里就用到了观察者模式.在软件系统中,当一个对象的行为依赖于另一个对象的状态 ...

  2. js attribute 和 jquery attr 方法

    attribute 是原生js dom 对象上的一个属性,这个属性有很多子属性,比如 isId(判断属性是否是Id) , name (获取属性名称) , value (获取属性值),attribute ...

  3. 在Ubuntu下安装ovs-dpdk

    在Ubuntu下安装ovs-dpdk 参考资料:https://software.intel.com/zh-cn/articles/using-open-vswitch-with-dpdk-on-ub ...

  4. CYQ.Data V5 从入门到放弃ORM系列:教程 - AppConfig、AppDebug类的使用

    1:AppConfig类的介绍: Public Static (Shared) Properties IsEnumToInt 是否使用表字段枚举转Int方式(默认为false). 设置为true时,可 ...

  5. 用命令行工具创建 NuGet 程序包

    NuGet.exe 下载地址 本文翻译自: https://docs.nuget.org/Create/Creating-and-Publishing-a-Package https://docs.n ...

  6. 腾讯云下安装 nodejs + 实现 Nginx 反向代理

    本文将介绍如何给腾讯云上的 Ubuntu Server 12.04 LTS 64位主机安装 node 及 nginx,并简单配置反向代理. 笔者在整个安装过程中遇到不少麻烦(不赘述),如果你希望少踩坑 ...

  7. iOS---基于对Sqlilte3的二次包装的第三次包装--->JKDBModel ,一个好用的离线缓存库

    https://github.com/Joker-King/JKDBModel 1.将FMDB和DBModel拖入项目中,然后添加libsqlite3.dylib   2. #import " ...

  8. python学习 正则表达式

    一.re 模块中 1.re.match #从开始位置开始匹配,如果开头没有match()就返回none 语法:re.match(pattern, string, flags=0) pattern 匹配 ...

  9. nodejs模块中exports和module.exports的区别

    通过Node.js的官方API可以看到Node.js本身提供了很多核心模块 http://nodejs.org/api/ ,这些核心模块被编译成二进制文件,可以require('模块名')去获取:核心 ...

  10. jQuery:实现网页的打印功能

    实现的打印功能大致跟浏览器的 Ctrl+P 效果一样 一.直接上代码 <!DOCTYPE html> <head> <meta charset="utf-8&q ...