2010-04-21 114 views
13

当运行有一个博客区的MVC 2 Areas example和博客控制器的URL看起来像这样:ASP.NET MVC区域:如何在URL中隐藏“区域”名称?

格式http://localhost:50526/Blog/Blog/ShowRecent

使用rootUrl/AREANAME/ControllerName/ActionName

刚走发现MVC领域,它似乎是组织代码的好方法,即为每个部分创建一个区域,在我的情况下,每个部分都有自己的控制器。这意味着每个AreaName = ControllerName。这样做的效果是在URL中的双AreaName/ControllerName路径例如/博客/博客/上面

没有一个完整的路由清晰的理解,我怎么能设置路由到不显示AreaName?

编辑:

我想,以减少与路线的工作量,因为这些看似彼此影响(即需要特定的顺序),并可能导致重大头痛:-)在转换现有Web窗体应用程序到MVC,我已经转换了几个核心部分,这些部分分别具有一个控制器和相当数量的View/Actions,尽管大部分数据访问都是在程序集中,但Model/ViewData类的数量正在增加...... I我目前在这些部分(或区域)的根模型/视图文件夹中创建了子文件夹,并且希望除了组织代码(使用覆盖该区域的基本路线)之外,创建区域将以相同的方式工作 对此有何评论?

+1

出于好奇,如果你不想额外的文件夹,为什么要实现你的应用程序? – GalacticCowboy 2010-04-21 11:04:46

+1

Btw ..不要过度使用路线.. 如果您制作的区域只有一个控制器,那么您确定首先需要一个单独的区域吗? :) – 2010-04-21 11:06:30

+0

@GalacticCowboy,Artiom:好点,并且在上面添加了更多评论......看起来好像区域可能不是要走的路,或者当我们需要开始组织更大/特定的部分时,开始使用区域。 – 2010-04-21 12:55:30

回答

18

在每个区域的文件夹中,您会看到一个*AreaName*AreaRegistration.cs文件。这是存储区域路由规则的地方。默认情况下,当它们生成时,它们将包含区域名称之前的一切。问题是:如果从路由中删除区域名称“文件夹”,路由将捕获所有“标准”{控制器}/{操作}/{id}请求。这显然不是你想要的。

为了克服这个问题,你可以在路由上添加正则表达式过滤器,这个过滤器基于那个路由中存在的控制器名称。缺点?你将无法在应用程序中拥有两个同名的控制器(至少不使用标准路线..你总是可以想到不同的路线来访问它们:))

最后..具有这种结构:

/地区
/Areas/Blog/Controllers/BlogController.cs
/Areas/Blog/Controllers/FeedController.cs
/Areas/User/Controllers/UserController.cs
/Controllers/PageController.cs

你应该拥有的是某事像这样: 在BlogAreaRegistration.cs:

context.MapRoute(
    "Blog_default", 
    "{controller}/{action}/{id}", 
    new { action = "Index", id = UrlParameter.Optional }, 
    new { controller = "(Blog|Feed)" } 
); 

在UserAreaRegistration.cs:

context.MapRoute(
    "User_default", 
    "{controller}/{action}/{id}", 
    new { action = "Index", id = UrlParameter.Optional }, 
    new { controller = "(User)" } 
); 

在Global.asax中。cs:

public static void RegisterRoutes(RouteCollection routes) 
{ 
    context.MapRoute(
    "Default", 
    "{controller}/{action}/{id}", 
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
    ); 
} 
protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 

    RegisterRoutes(RouteTable.Routes); 
} 

请注意,在global.asax区域注册是第一位! :)

UPD:根据您的问题更新 : 有我们,你必须考虑到,如果你会使用领域之一重大的事情:如果你有一个区域间的链接,你会也必须在链接中提供区域名称。例如。

<%: Html.ActionLink("Link text", "Action", "Controller", new { area = "Blog", id = 4, title = "page-title" }); %> 

你明白了。

关于多个模型/视图,此刻,我喜欢以下结构的本

/代码/ //帮手,没有被转移到库
/模型/数据扩展类/ //该EF类+验证类在这里每个控制器存储

到目前为止,它工作正常
/模型/的ViewModels/{}控制器/ //视图模型,我设法保持相对有组织的解决方案。正如我所说,我创建至今的唯一区域是Admin区域,因为它是从网站:)其余太大的不同

+0

谢谢!我需要对此进行研究(以及一个很好的想法),看看在目前的情况下使用区域会带来怎样的好处... – 2010-04-21 12:59:25

+1

只是为了给你我目前的状况:我正在开发自己的博客引擎(可能不公开,只为我自己写)。目前大多数控制器都在默认/ Controllers文件夹中。页面,注册/认证,评论,文件下载等。但我创建了一个管理区域,因为我认为它应该与常规代码分开+有不同的外观(单独的Contect文件夹等)。最后这取决于你) – 2010-04-21 13:06:16

+0

添加了对答案的更新,回答了你对问题的更新..嗯..听起来很奇怪:D – 2010-04-21 13:15:22

1

只是为了回答你原来的问题,如果别人在读这:

不要命名您的[默认]控制器博客。这就是为什么你得到博客/博客{区域/控制器}。您可以给它一个完全不同的名称:即博客/视图,博客/帖子,博客/最近等,或者像家一样的默认。在这种情况下,如果你也有家庭在外面的区域你的控制器,你会想你的命名空间默认控制器:

routes.MapRoute("Default", 
    "{controller}/{action}/{id}", 
    new { controller = "Home", action = "Index", id = UrlParameter.Optional}, 
    new[] { *appname*.Controllers" }); 

这将确保“/”和“/博客”去了适当的“家”控制器。如果你搜索重复的家庭控制器错误,你会发现更多。