详解ASP.NET MVC 2中的Area特性

开发 后端
新的ASP.NET MVC 2预览版发布后,其中有一项Area特性增强。本文将为大家详细讲述Area特性的来龙去脉。

51CTO在1月曾专访过微软MVP衣明志老师,主要话题就是ASP.NET MVC 2。其中我们曾谈到Area特性,在这里特组织这篇文章供大家了解ASP.NET MVC 2中的Area。想学习更多ASP.NET MVC,请参考教程《ASP.NET MVC框架视频教程

最近装了mvc2 pr2版本,看了下说明文档,里面着重提示说更新了area项目,因此着重看了一下。若干心的,和大家共享,有错没错,欢迎大家拍砖。

没有Areas前相同问题的处理

在mvc1.0时代,如果要将网站按目录结构来区分。例如

  1. Website/Index  
  2. Admin/ Index  
  3. User/ Index  
  4. ……/…… 

通常都是在Views下面建立若干个和Controller相对应的目录,然后在里面放置aspx页面

  1. Views\Website\Index  
  2. Views\Admin\Index  
  3. Views\User\Index  
  4. Views\.......\....... 

这样建立若干个目录

其实这样也没什么不好,***不好的可能就是随着业务的需要,结构需求会越来越多,views目录下面的文件夹越来越多,更或者你需要更细结构的页面路径,例如:

  1. Website/Product/Index  
  2. Website/Catalog/Index  
  3. Website/Contect/Index 

当然,你可以用UrlRouteing或者ViewEngine搞定这些问题。但是毫无疑问,随着网站的运行日久,同一个Controller目录下的文件会越来越多,对于同一个Controller下的ActionResult的命名和UrlRouting里面的维护带来不小的麻烦。给管理带来不方便【个人理解】。

现在出Areas之后,这个问题有所缓解。还是如上的Url

  1. Website\Product\Index  
  2. Website\Catalog\Index  
  3. Website\Order\Index  
  4. Website\Contact\Index 

可以使用mvc2.0新增的Area来解决这个问题

建立项目

首先,用mvc2建立一个新项目,在网站根目录下建立Areas文件夹,在Areas文件夹建立你要区分的目录,例如本例的Website,然后继续在Website目录下增加Views目录,继续在views目录下增加需要分类管理Controller目录和建立aspx文件。使文件结构形成

  1. Areas\Website\Views\Product  
  2. Areas\Website\Views\ Catalog  
  3. Areas\Website\Views\ Order  
  4. Areas\Website\Views\ Contact 

建立项目 

到原有默认的views目录将web.config复制到现在的新的views目录,你甚至现在可以把原有的views目录删除掉

建立Areas区域UrlRouting

随便找个地方,建立一个新的类,继承AreaRegistration实现抽象类

修改Global.sas

  1. protected void Application_Start()  
  2.         {  
  3. AreaRegistration.RegisterAllAreas();  
  4. //注册区域Url规则,注意先后顺序  
  5. RegisterRoutes(RouteTable.Routes);  
  6.         } 
为区域页面建立Controller类

为区域页面建立Controller类没什么区别,可以建立在另外一个外部类库项目上,***需要注意的就是命名空间需要和注册Area规则的类的命名空间的前导一致。我们知道,在不使用Areas的时候Controller是不受namespace约束的。也就是说只要你有一个Controller名,而不管他在哪个命名空间下都是可以起作用的,如果我们在不同的命名空间建立2个相同的Controller类名,编译的时候不会出错,但是运行mvc网站的时候会提示存在2个相同的Controller类,系统不知道使用哪个。但是Areas却有所限制,他一定要命名空间的前导和AreaRegistration类得命名空间相同。例如:我建立的AreaRegistration网站项目命名空间为Valor.Asmyna.Areas.Website然后我将Controller分开作为一个独立的类库,如果我随便写一个命名空间空间,这个Controller对于Area里面的views是不起作用的,但是他却对原始Views目录的Controller起作用,只有将他的命名空间设置成Valor.Asmyna.Areas.Website.xxx.xxx的前导才起作用

  1. namespace Valor.Asmyna.Areas.Website  
  2.  
  3. {  
  4.  
  5.     public class HomeController : Controller  
  6.  
  7.     {  
  8.  
  9. public ActionResult Index()  
  10.         {  
  11.             ViewData["title"] = "Website/Home/Index";  
  12.             return View();  
  13.         }  
  14.     }  
  15. public class ProductController : Controller  
  16.     {  
  17.         public ActionResult Index()  
  18.         {  
  19. ViewData["title"] = "Website/Product/Index";  
  20. return View();       }  
  21.     }  
  22. public class ContentController : Controller  
  23.     {  
  24.         public ActionResult Index()  
  25.         {  
  26.   ViewData["title"] = "Website/Content/Index";  
  27.     return View();  
  28.         }   }  

Ok,到浏览器测试一下看看

Area结构完全一致会出现的问题

我们继续在Area目录下增加一个Home目录,在他的Veiws目录下也增加三个相同的controller目录

浏览器中测试

直接在刚才注册Website AreaRegistration命名空间为他注册一个Area规则,用默认系默认的Controller为Home.,

对2个路径进行访问:

/Website/Product

/Home/Product

这个时候controller对于这2个area目录的views都能起作用。在页面打印得到的结果一致

View结果

显然这样是不对的.由此我们刚才想到Area的Controller的选择名命名空间限制问题。那我们他们分开来注册看看。修改Home区域的AreaRegistration的命名空间和在为HomeArea建立一个Controller类,使他们的命名空间一致。这次我们用Valor.Asmyna.Areas.Website

  1. namespace Valor.Asmyna.Areas.Home{  
  2.    public class HomeController : Controller  
  3.     {  
  4.        public ActionResult Index()  
  5.         {  
  6.             ViewData["title"] = "Home/Content/Index";  
  7.             return View();  
  8.         }   }  
  9. public class ProductController : Controller  
  10.     {  
  11.         public ActionResult Index()  
  12.         {  
  13.             ViewData["title"] = "Home/Content/Index";  
  14.             return View();  
  15.         }}  
  16.     public class ContentController : Controller  
  17.     {  
  18.         public ActionResult Index()  
  19.         {  
  20.             ViewData["title"] = "Home/Content/Index";  
  21.             return View();  
  22.         }  
  23.     }}  
  24. namespace Valor.Asmyna.Areas.Home  
  25. {  
  26.     public class HomeController : Controller  
  27.     {  
  28.         public ActionResult Index()  
  29.         {  
  30.             ViewData["title"] = "Home/Home/Index";  
  31.             return View();  
  32.         }   }  
  33. public class ProductController : Controller{  
  34.        public ActionResult Index()  
  35.         {  
  36.             ViewData["title"] = "Home/Product/Index";  
  37.             return View();  
  38.         }    }  
  39.     public class ContentController : Controller  
  40.     {  
  41.         public ActionResult Index()  
  42.         {  
  43.             ViewData["title"] = "Home/Content/Index";  
  44.             return View();  
  45.         }  
  46.     }  

编译之后访问,各自分别为自己的Controller处理了

Home/Product

结果1

Website/Product

结果2

原文标题:使用mvc2里面的area让网站更有条理

链接:http://www.cnblogs.com/tthxnz/archive/2009/11/12/1602097.html

【编辑推荐】

  1. 专访微软MVP衣明志:走进ASP.NET MVC 2框架开发
  2. 详解ASP.NET MVC 2中强类型HTML辅助方法
  3. ASP.NET MVC 2 RC版全新发布 增强HTML控制
  4. 详解ASP.NET MVC 2自定义验证
  5. 详解ASP.NET MVC对表进行通用的增删改
责任编辑:彭凡 来源: 博客园
相关推荐

2010-10-12 09:52:02

ASP.NET MVC

2010-12-07 09:38:15

ASP.NET MVC

2009-10-29 09:15:32

ASP.NET MVCDropDownLis

2010-09-15 09:18:21

ASP.NET MVC

2010-10-08 14:32:32

ASP.NET MVCNuPack

2011-04-14 09:19:22

ASP.NET MVC

2010-01-18 09:25:33

ASP.NET MVC

2009-11-24 15:11:21

ASP.NET MVC

2010-03-19 09:17:16

ASP.NET MVC

2014-08-26 09:22:40

ASP.NET MVCRouting

2011-01-15 23:07:59

2009-09-10 09:50:47

ASP.NET MVC

2009-09-18 10:20:26

PRG数据验证

2009-07-22 13:16:04

MvcAjaxPaneASP.NET MVC

2009-12-01 09:30:34

ASP.NET MVC

2015-06-18 17:37:19

ASP.NET

2009-07-31 12:43:59

ASP.NET MVC

2009-07-20 16:44:56

ASP.NET MVCIValueProvi

2009-07-24 13:20:44

MVC框架ASP.NET

2010-10-09 08:41:40

Mono 2.8
点赞
收藏

51CTO技术栈公众号