现有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. Linux网卡驱动安装、防火墙原理

    安装网卡驱动程序: 需要检查是否安装kernel依赖包: rpm –q kernel-devel #检查kernel依赖包是否安装 yum –y install kernel-devel 检查gcc和 ...

  2. UML类图(下):关联、聚合、组合、依赖

    前言 上一篇文章UML类图(上):类.继承.实现,讲了UML类图中类.继承.实现三种关系及其在UML类图中的画法,本文将接着上文的内容,继续讲讲对象之间的其他几种关系,主要就是关联.聚合.组合.依赖, ...

  3. 不得不知的CLR中的GC

    引言 GC 作为CLR的垃圾回收器,让程序员可以把更多的关注度放在业务上而不是垃圾回收(内存回收)上.其实很多语言也有类似的东东, 如Java也有JIT 等等 GC基本概念 垃圾回收机制的算法有好多种 ...

  4. dynamic-css 动态 CSS 库,使得你可以借助 MVVM 模式动态生成和更新 css,从 js 事件和 css 选择器的苦海中脱离出来

    dynamic-css 使得你可以借助 MVVM 模式动态生成和更新 css,从而将本插件到来之前,打散.嵌套在 js 中的修改样式的代码剥离出来.比如你要做元素跟随鼠标移动,或者根据滚动条位置的变化 ...

  5. ABP框架 - 模块系统

    文档目录 本节内容: 简介 模块定义 生命周期方法 PreInitialize(预初始化) Initialize(初始化) PostInitialize(提交初始化) Shutdown(关闭) 模块依 ...

  6. TODO:字节的那点事Go篇

    TODO:字节的那点事Go篇 (本文go version go1.7.3 darwin/amd64) 在Golang中string底层是由byte数组组成的. fmt.Println(len(&quo ...

  7. 游戏服务器菜鸟之C#初探三游戏服务

    在经过上述2番折腾之后,最后决定使用TCP进行通信,所以在一次进行重构 主要重构的要点 1.将过来的HTPP请求,重构为TCP请求: 2.使用组件FluenScheduler进行怪物的定时刷新,和定时 ...

  8. c#文件操作

    1.创建文件夹 //using System.IO; Directory.CreateDirectory(%%1);   2.创建文件 //using System.IO; File.Create(% ...

  9. 【java】细说 JAVA中 标注 注解(annotation)

    Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用 下面我们来详细说说这个注解,到底是怎么一 ...

  10. vue+node+es6+webpack创建简单vue的demo

    闲聊: 小颖之前一直说是写一篇用vue做的简单demo的文章,然而小颖总是给自己找借口,说没时间,这一没时间一下就推到现在了,今天抽时间把这个简单的demo整理下,给大家分享出来,希望对大家也有所帮助 ...