现有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,嘿嘿,下班啦
 
 
 
 
 
 
 
 
 
 
 
 

最新文章

  1. Linux上如何查看物理CPU个数,核数,线程数
  2. laravel 在windows中使用一键安装包步骤
  3. POJ 2229 Sumsets
  4. 浴室随想——RogueLike随想
  5. python range() 和xrange()的区别
  6. 如何把你的图标转换成web字体
  7. new_things
  8. js画线
  9. ibatis.net 多线程的调试
  10. 多线程同步、异步(BeginInvoke)
  11. JS中slice,splice,split的区别
  12. 《4》CentOS7.0+OpenStack+kvm云平台部署—配置Nova
  13. python自学笔记(十)语句与数据结构应用
  14. Hadoop学习笔记一(HDFS架构)
  15. React(v16.8.4)生命周期详解
  16. BeanUtil拷贝
  17. MT【1】终点在球面上的向量
  18. JavaScript高级用法一之事件响应与网页交互
  19. python的队列和栈
  20. Apache poi简介及代码操作Excel

热门文章

  1. eclipse如何添加Memory Analyzer
  2. git远程库GitHub
  3. BZOJ 1006 【HNOI2008】 神奇的国度
  4. 集成基于CAS协议的单点登陆
  5. 借助GitHub托管你的项目代码
  6. Entity Framework 6 Recipes 2nd Edition(10-6)译 -&gt; TPT继承模型中使用存储过程
  7. 易懂 易上手的cookie 最简单明了 js中cookie的使用方法及教程
  8. ERROR ITMS-90167: &quot;No .app bundles found in the package&quot;错误
  9. Redis数据结构详解之List(二)
  10. 牛逼的css3:动态过渡与图形变换