您好,欢迎访问一九零五行业门户网

[ASP.NET MVC 小牛之路]08 - Area 使用

[asp.net
mvc 小牛之路]08 - area 使用
asp.net mvc允许使用 area(区域)来组织web应用程序,每个area代表应用程序的不同功能模块。这对于大的工程非常有用,area 使每个功能模块都有各自的文件夹,文件夹中有自己的controller、view和model,但对于管理也增加了一定的难度。
本文目录
创建area
右键工程选择 添加->区域,弹出如下填写area的对话框:
点击添加后,工程目录结构如下:
和创建一个空mvc工程结构类似,admin area 有自己的 controllers、models 和 views 文件夹,不一样的地方就是多了一个 adminarearegistration.cs 文件,这个文件中定义了一个叫 adminarearegistration 的类,它的内容如下:
namespace mvcapplication1.areas.admin { public class adminarearegistration : arearegistration { public override string areaname { get { return "admin"; } } public override void registerarea(arearegistrationcontext context) { context.maproute( "admin_default", "admin/{controller}/{action}/{id}", new { action = "index", id = urlparameter.optional } ); } } }
系统自动生成的 adminarearegistration 类继承至抽象类 arearegistration,并重写
了 areaname 属性和 registerarea 方法。在 registerarea 方法中它为我们定义了一个默认路由,我们也可在这个方法中定义专属于admin area的的其他路由。但有一点要注意,在这如果要给路由起名字,一定要确保它和整个应用程序不一样。
arearegistrationcontext 类的 maproute 方法和 routecollection 类的 maproute 方法的使用是一样的,只是 arearegistrationcontext 类限制了注册的路由只会去匹配当前 area 的 controller,所以,如果你把在 area 中添加的 controller 的默认命名空间改了,路由系统将找不到这个controller 。
registerarea 方法不需要我们手动去调用,在 global.asax 中的 application_start 方法已经有下面这样一句代码为我们做好了这件事:
protected void application_start() { arearegistration.registerallareas(); webapiconfig.register(globalconfiguration.configuration); filterconfig.registerglobalfilters(globalfilters.filters); routeconfig.registerroutes(routetable.routes); bundleconfig.registerbundles(bundletable.bundles); }
调用 arearegistration.registerallareas 方法让mvc应用程序在启动后会寻找所有继承自 arearegistration 的类,并为每个这样的类调用它们的 registerarea 方法。
注意:不要轻易改变 application_start 中注册方法的顺序,如果你把routeconfig.registerroutes方法放到arearegistration.registerallareas方法之前,area 路由的注册将会在路由注册之后,路由系统是按顺序来匹配的,所以这样做会让请求 area 的 controller 匹配到错误的路由。
area的运行
在area中添加controller、view和model和一般的添加是一样的。在这,我们在admin area中添加一个名为 home 的controller,代码如下:
public class homecontroller : controller { public actionresult index() { return view(); } }
然后我们再为index acton添加一个view,代码如下:
@{ viewbag.title = "index"; layout = null; } <!doctype html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>index</title> </head> <body> <p> <h2>admin area index</h2> </p> </body> </html>
运行应用程序,然后将url定位到/admin/home/index,下面是运行结果:
到这,我们已经看到,area中的的工作流程其实就是和根目录下的流程是一样的。但area并不是一个完全独立的工作空间,我们下面来看看。
controller的歧义问题
试想一下,如果我们现在在根目录的 controller 文件夹中也添加一个名为 home 的 controller,然后我们通过把url定位到 /home/index,路由系统能匹配到根目录下的 controller 吗?
在根目录的 controllers 文件夹中添加好 homecontroller 后,为index添加view,内容随意:
... <body> <p> <h2>root index</h2> </p> </body> ...
路由不改动,我们使用 routeconfig.cs 文件中系统定义的默认路由:
public static void registerroutes(routecollection routes) { routes.ignoreroute("{resource}.axd/{*pathinfo}"); routes.maproute( name: "default", url: "{controller}/{action}/{id}", defaults: new { controller = "home", action = "index", id = urlparameter.optional } ); }
运行程序,将url定位到 /home/index。结果我们会看到如下错误信息:
出现这个问题是因为路由系统进行匹配的时候出现了controller同名的歧义。
当area被注册的时候,area中定义的路由被限制了只寻找 area 中的controller,所以我们请求 /admin/home/index 时能正常得到 mvcapplication1.areas.admin.controllers 命名空间的 homecontroller。然而我们在routeconfig.cs文件的registerroutes方法中定义的路由并没有类似的限制。
为了解决这个问题,我们需要在routeconfig.cs文件中定义的路由中加上对应的 namespaces 参数。routeconfig.cs 中修改后的路由如下:
public static void registerroutes(routecollection routes) { routes.ignoreroute("{resource}.axd/{*pathinfo}"); routes.maproute( name: "default", url: "{controller}/{action}/{id}", defaults: new { controller = "home", action = "index", id = urlparameter.optional }, namespaces: new[] { "mvcapplication1.controllers" } ); }
运行程序,如下结果说明解决了同名歧义问题:
添加了 namespaces 参数后,路由系统在对这个路由进行匹配时,优先匹配指定命名空间的controller,如果匹配到则即刻停止查找,如果在指定的命名空间下没有匹配到对应的controller,再按照一般的方式进行匹配。
生成area url链接
关于area的url链接生成,可以分为这么三种情况:第一种是在当前area生成指向当前area的链接;第二种是生成指向其他area的链接;第三种是在某个area中生成指向根目录的链接。下面是这三种情况生成链接的方法,使用的路由定义是系统默认的。
如果要在area中生成当前area的url链接,直接用下面的方法就行:
@html.actionlink("click me", "about")
它根据当前所在的area和controller会生成如下html代码:
<a href="/admin/home/about">click me</a>
如果要生成其他area的url链接,则需要在html.actionlink方法的匿名参数中使用一个名为area的变量来指定要生成链接的area名称,如下:
@html.actionlink("click me to go to another area", "index", new { area = "support" })
它会根据被指定的area去找路由的定义,假定在support area中定义了对应的路由,那么它会生成如下链接:
<a href="/support/home/index">click me to go to another area</a>
如果要在当前area生成指根目录某个controller的链接,那么只要把area变量置成空字符串就行,如下:@html.actionlink("click me to go to top-level part", "index", new { area = "" })
它会生成如下html链接:<a href="/home/index">click me to go to top-level part</a>
以上就是[asp.net mvc 小牛之路]08 - area 使用的内容。
其它类似信息

推荐信息