更改区域在 Razor MVC 中创建方式的最佳方式是什么?

What's the best way to change how Areas get created in Razor MVC?

我正在过渡到在项目中使用区域,每次我创建一个新项目时,我都必须更改一些内容以使其符合我希望的工作方式。更改涉及:

我不想每次创建新区域时都必须做这些相同的事情,因为我担心约定会被遗忘并且有些事情会搞砸。有没有办法修改 New > Area 的默认值?或者是否可以制作一个新的文件模板来满足我的需求?

I am transitioning to using Areas in a project

几个月来我一直在做类似的事情,但是从一个旧的 WebForms 项目开始,通过 VS 2013 的 Add -> New Scaffolded Item... 功能添加 MVC 组件,以便在服务器上利用 MVC 的结构和路由边。我还在服务器端整合了 WebAPI 和 SignalR。我绝对还是一个初学者,但在类似的过程中可能会更进一步,这里是我对你想要实现的目标的一些想法和问题:


  • Removing one of the folders that gets created
  • Modifying the web.config file slightly
  • Adding a new file or two with some defaults

你在什么环境下开发?例如,如果您正在使用 VS 2013 的脚手架,您很可能可以修改 T4 模板以防止或重定向文件夹的创建,类,等等。 Here is a post addressing where you might find those templates, and here 只是 T4 的众多介绍之一。您计算机上模板的路径将根据 VS 版本而有所不同。通过修改或创建新模板,您应该能够相对轻松地完成上述所有 3 点。如果您在这样的环境中工作,我将尝试详细说明您可以如何修改开箱即用的模板(可能已经有很多您可以参考的帖子,但它们会做得更好)。


  • Modifying the AreaRegistration file slightly

如果您使用的是 MVC 5 或更高版本,我建议您使用属性路由。这在 API 范式(继承自 ApiController 而不是 Controller )内工作时似乎更标准,但我发现将其扩展到传统 MVC 控制器非常有用。

假设是 MVC 5,我建议修改 AppStart\RouteConfig.csRegisterRoutes() 方法,以启用属性路由,然后添加一个包罗万象的路由,例如:

routes.MapMvcAttributeRoutes();

routes.MapRoute(
    "NotFound",
    "{*url}",
    new {
        controller = "Error",
        action = "Index"
    });

那时我会删除 xAreaRegistration.cs 文件,并从 Global.asax 中删除对 RegisterAllAreas() 的调用,但您不必走那么远。然后我根据需要用属性装饰我的控制器的 类(无论它们在哪里)和它们的方法。使用属性路由,我已经能够将自己从传统的 MVC 约定中解放出来。我仍然可以回退到他们,但我可以将我的控制器放在我项目中的任何地方,并轻松定义他们的动作路线。

话虽这么说,您可能应该遵循一些类似路线组的组织标准,这样随着项目的发展,您不会发现自己浪费大量时间来搜索所有 controllers/actions 匹配的一些路线路线。


下面是一个简单的示例,它说明了如何将 URI 实际转换为方法调用:

如果我的控制器 ctl 具有操作 act逻辑上位于 区域 ar,URI 为 http://localhost/ar/ctl/a/1,将被路由到下面的 MyControllerNameDoesNotMatter.Index(1),通过使用属性修饰,例如:

[RouteArea("ar")]
[RoutePrefix("ctl")]
public class MyControllerNameDoesNotMatter : Controller {
    ...        
    [Route("a/{optionalParamDefaultsToNegativeOne=-1}")]
    public ActionResult Index(int optionalParamDefaultsToNegativeOne) {
        ...
    }
}

这种查看区域的方式 比物理方式 更符合逻辑,因为 MyControllerNameDoesNotMatter.cs 文件不必位于 Area\ar\Controllers 文件夹中。自从采用它以来,我实际上已经不再使用 Area 脚手架,除了在非常高的层次上布置应用程序模块 - 想想可以是独立 SPA 的子应用程序。

我试图使 "catch-all" 路由属性成为基础,并将其从 RouteConfig.cs 中删除,但我未能成功完成此操作。问题是路由优先级。它可以很好地作为无效路由的包罗万象。但是对于有效路由,多 (2) 条路由最终会被匹配,因为这两条属性路由具有相同的优先顺序。而在 RouteConfig.cs 中定义的 catch-all, 在注册所有属性路由后 ,属性路由优先。我找到了试图解决这个问题的混合答案。在某些时候,Route 属性似乎有一个 NumberOrder 参数,但我没有运气。这似乎是一个悬而未决的问题。 Just one of many SO questions,没有人回答。

编辑以说明 mvc4 标签

我在发布之前没有看到 mvc4 标签。有一些可用的 nuget 包可以实现大部分相同的功能,例如 scaffolding and attribute routing 用于早期版本的 MVC。