Asp.Net 5使用Area及自定义Area
Asp.Net Mvc里有一个叫做Area的技术,就是可以把不同逻辑组件的controller, view等放到不同的文件夹里。比如所有管理相关的都放到Admin area里。其实之前我一直对这个功能不太感冒,并不觉得能解决什么大问题,如果项目规模较大的话,肯定是很多开发协同开发,这时候很大的一个问题是版本库冲突的问题以及一个模块build不过导致其他模块受难。我觉得area并不能解决这个问题,直到我看到了Orchard的源码。
Orchard的思路简单来说就是,在Areas文件夹下建了好几个web工程,因为web工程下面会有Controllers, Views的文件夹结构,是完全符合area的结构定义的,然后把这个Areas文件夹从web project里exclude出去,在工程里就看不到了,最后再把这些工程加到solution里。这样不同模块的开发可以创建多个solution,每个solution里只引用自己所需的最少的工程就可以,避免了版本库冲突以及build失败的问题了。
当初我看到这种做法的时候不由得眼前一亮,这种结构可以很好地解决协同开发的问题,而且实现组件化,热插拔也都方便了许多。所以当开始学习Asp.Net 5(area实际上是Mvc的概念,说Mvc 6更严谨)的时候,一开始就想到了试试新框架的area功能。结果发现和以前的版本并不太一样。这里不做比较了,直接上代码。
首先在web工程里创建出Areas文件夹以及相应的结构目录
-Areas
--Management
---Controllers
----HomeController.cs
--Views
---_ViewStart.cshtml
---Home
----Index.cshtml
HomeController的Index action直接return View();
, _ViewStart.cshtml是指定layout的,和web工程里的一样,当然你可以自己定义新的模板,自己可以添加_GlobalImport.cshtml以加入TagHelper和命名空间之类的,不多说。
真正的工作有两样,一是设置路由,二是标记Area。目前没发现MVC5里的area自动发现功能,所以需要给area的controller加上Area
标签。
[Area("Management")]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
然后在web工程的Startup里添加路由。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
{
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "area",
template: "{area:exists}/{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index" });
});
}
启动项目,浏览器里输入url localhost:8888/Management
就看到这个Management area的home页面了。
然后问题来了,我们写代码的时候,很多情况下都需要做一些自定义的东西,下面来看一下一些自定义的方法,主要处理三个问题:1,文件夹名不叫Areas,而是叫modules;2,不在Controller上加Area标签,自动发现;3,url里不包含area的名字。
第一个问题很好解决,就是告诉Razor引擎寻找View的时候别在Areas文件夹下找就可以了。实现一个自定义的RazorViewEngine,然后改变一下默认的搜索路径。别忘了把之前的Areas文件夹改名为modules。
public class CustomLocationRazorViewEngine : RazorViewEngine
{
public CustomLocationRazorViewEngine(IRazorPageFactory pageFactory, IRazorViewFactory viewFactory, IViewLocationExpanderProvider viewLocationExpanderProvider, IViewLocationCache viewLocationCache)
: base(pageFactory, viewFactory, viewLocationExpanderProvider, viewLocationCache)
{
var areaViewLocationFormats = AreaViewLocationFormats as string[];
areaViewLocationFormats[0] = "/modules/{2}/Views/{1}/{0}.cshtml";
areaViewLocationFormats[1] = "/modules/{2}/Views/Shared/{0}.cshtml";
}
}
第三个问题也比较好解决,只要在制定路由规则的时候,把area信息传一下就行了。
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "area",
template: "manage/{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index", area = "Management" });
});
第二个问题略微麻烦一点,什么样的Controller才是area里的Controller呢?即便能判定出这样的Controller来,又把它算到哪个area下面去呢?这个其实各个项目都有不同的需求,这里就假设,主web工程里的Controller的namespace都是AspNetAreaDemo.Controllers,除了这种命名空间的,都是area里的Controller,而area名字也通过namespace来体现。就是默认area Controller的命名空间都是XXX.XXX.XXX.AreaName.Controllers,这样用.
分割一下,取倒数第二个就可以了。实际开发中,可能会以assembly的name,project的name等来作为area name,甚至干脆维护一个映射。
现在策略有了,怎么才能自动地给Controller加上Area标签呢。看看源码,AreaAttribute
实际上是IRouteConstraintProvider
接口的一个实现类,而这个接口是在ControllerModel
类里有所体现的,是一个集合。所以我们需要做的就是给符合条件的ControllerModel
的RouteConstraints
集合里添加一个AreaAttribute
。代码如下
public class AreaAutoDiscoverControllerModelConvention : IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
var ns = controller.ControllerType.Namespace;
if (ns != "AspNetAreaDemo.Controllers")
{
var segments = ns.Split(new char[] { '.' });
var areaName = segments[segments.Length - 2];
controller.RouteConstraints.Add(new AreaAttribute(areaName));
}
}
}
准备工作做完了,最后只要把自定义的RazorViewEngine和ControlleModelConvention添加到程序里就可以了。还是Startup类。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSubKey("AppSettings"));
services.AddMvc();
services.ConfigureMvc(options =>
{
options.ViewEngines.Clear();
options.ViewEngines.Add(new ViewEngineDescriptor(typeof(CustomLocationRazorViewEngine)));
options.Conventions.Add(new AreaAutoDiscoverControllerModelConvention());
});
}
启动程序,输入url localhost:8888/manage
就看到新的页面了。
Asp.Net 5使用Area及自定义Area的更多相关文章
- [ASP.NET MVC 小牛之路]08 - Area 使用
ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块.这对于大的工程非常有用,Area 使每个功能模块都有各自的文件夹,文件夹中有自己的Cont ...
- MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器
实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器 MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过A ...
- 【ASP.NET MVC 学习笔记】- 09 Area的使用
本文参考:http://www.cnblogs.com/willick/p/3331519.html 1.ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,这对于大的工程非常有用, ...
- 把某个asp.net 控件 替换成 自定义的控件
功能:可以把某个asp.net 控件 替换成 自定义的控件 pages 的 tagMapping 元素(ASP.NET 设置架构) 定义一个标记类型的集合,这些标记类型在编译时重新映射为其他标记类型. ...
- asp.net core参数保护之自定义要保护的参数类型
asp.net core参数保护之自定义要保护的参数类型 Intro 为了实现 asp.net core 下的参数保护,扩展了asp.net core 中 DataProtection,可以自动化的保 ...
- ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则
ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...
- 新西兰程序员 ASP.NET网站中设置404自定义错误页面
新西兰程序员 ASP.NET网站中设置404自定义错误页面 在用ASP.NET WebForm开发一个网站时,需要自定义404错误页面. 做法是这样的 在网站根目录下建立了一个404.html的错误页 ...
- ASP.NET MVC Area使用-将Area设置成独立项目
环境说明:Vistual Studio 2013 MVC 4.0 其实关于ASP.NET MVC Area使用的基础知识可以参考 http://www.cnblogs.com/willick/p/33 ...
- ASP.NET Core MVC 之区域(Area)
区域(Area)是一个 ASP.NET MVC 功能,用于将相关功能组织为一个单独的命名空间(用于路由)和文件结构(用于视图).使用区域通过向控制器和操作添加 一个路由参数(area)来创建用于路由目 ...
随机推荐
- C#生成缩略图代码
/**//// <summary> /// 生成缩略图 /// </summary> /// <param name=&q ...
- 也用 Log4Net 之走进Log4Net (四)
转载地址:http://www.cnblogs.com/dragon/archive/2005/03/24/124254.html 我是转的别人的内容,我觉得他写的非常好,所以我把其中三分之二转了过来 ...
- 浅析WCF与WebService、WPF与Silverlight 区别
由于在<Windows服务调用Quartz.net 实现消息调度>中,涉及到ASP.NET Web Service //WebServiceSoapClient client = new ...
- 数学(扩展欧几里得算法):HDU 5114 Collision
Matt is playing a naive computer game with his deeply loved pure girl. The playground is a rectangle ...
- ccr test
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 第一个App“今日材料报价”上架,记录一下【原】
App Store地址:https://itunes.apple.com/us/app/jin-ri-cai-liao-bao-jia/id967274552?l=zh&ls=1&mt ...
- RequestHander类介绍
RequestHander是一个抽象类,是一个线程.它封装了一个Socket.代码不难: package org.simpleHTTPServer; import java.io.IOExceptio ...
- 射频识别技术漫谈(9)——动物标签HDX【worldsing笔记】
半双工(HDX,Half Duplex)技术是ISO11784/11785中规定的另一种标签与读写器之间的通讯方式.读写器先打开射频场对标签充电以激活标签,然后关闭磁场,标签在读写器磁场关闭的情况下向 ...
- jquery.layout框架分割线
css <link href="${base}/res/common/css/jquery.layout/jquery.layout.css" rel="style ...
- SpringMVC(三)
今天是学习Spring的第四天,今天终于又把Spring+SpringMVC+Mybatis(SSM)高了一遍,这次运行的代码和配置和昨天的不一样,今天运行的很成功. 主要学习的一点就是我今天使用的是 ...