现有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. 访问者模式(visitorpattern)

    /** * 访问者模式 * @author TMAC-J * 在客户端和元素之间添加一个访问者 * 当你需要添加一些和元素关系不大的需求时,可以直接放在访问者里面 * 或者是元素之间有一些公共的代码块 ...

  2. SAP CRM 将组件整合至导航栏中

    到现在,我们已经可以让组件独立地显示.我们只是运行它.让它显示在Web UI中.让我们把组件整合进导航栏,使我们可以在正常登录Web UI时访问它. 步骤一: 为你的UI组件主窗体创建一个内向插件. ...

  3. iOS app内存分析套路

    iOS app内存分析套路 Xcode下查看app内存使用情况有2中方法: Navigator导航栏中的Debug navigator中的Memory Instruments 一.Debug navi ...

  4. iOS 自定义方法 - 不完整边框

    示例代码 ///////////////////////////OC.h////////////////////////// ////  UIView+FreeBorder.h//  BHBFreeB ...

  5. docker – 你应该知道的10件事

      容器并不是一个全新的技术,但这并不妨碍Docker如风暴一样席卷整个世界. 如果你在IT圈里,你一定听说过Docker.就算与其他热门技术,如:Puppet/Chef,Hadoop或者MongoD ...

  6. svnserver hook python

    在使用中可能会遇到的错误排除 :1.Error: svn: 解析"D:\www\test"出错,或svn: E020024: Error resolving case of 'D: ...

  7. Bellman-Ford 单源最短路径算法

    Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法.该算法由 Richard Bellman 和 Leste ...

  8. Spring学习记录(十二)---AOP理解和基于注解配置

    Spring核心之二:AOP(Aspect Oriented Programming) --- 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软 ...

  9. 事件EVENT与waitforsingleobject的使用

    事件event与waitforsingleobject的配合使用,能够解决很多同步问题,也可以在数据达到某个状态时启动另一个线程的执行,如报警. event的几个函数: 1.CreateEvent和O ...

  10. 【Win 10应用开发】手动调用WCF服务

    调用服务最简单的方法就是,直接在VS里面添加服务引用,输入服务的地址即可,无论是普通Web服务,还是WCF服务均可.VS会根据获取到的元数据,自动生成客户端代码. 如果服务的调用量很大,应用广泛,可以 ...