使用区域和控制器名称进行路由(asp.net core)

问题描述 投票:0回答:2

为了防止我的应用程序变得混乱,我开始使用区域。但现在我总是要打电话:
http://localhost:49358/文档/文档/
而不是:
http://localhost:49358/文档/
如何更改按区域名称访问控制器的路线? (没有 HomeController)

我的项目中有以下文件夹结构:

Folderstructure inside my Project
我前往区域的路线代码如下所示:

routes.MapRoute(name: "areaRoute",template: "{area:exists}/{controller=Home}/{action=Index}");

我将 [Area("Document")] 标签放置在我的 DocumentController 中。

编辑:
根据 Shyju 和 Jamie Taylor 的建议,我选择了 HomeController。 (谢谢你们的快速回答和解释)

我的结构现在看起来像这样,并且路由按预期工作:
enter image description here

对我来说,拥有这么多 HomeController 和索引文件仍然有点令人失望。浏览代码不再那么容易了:
enter image description here

编辑2:
在对所有这些家庭控制器感到太恼火之后,我采用了 Jamie Taylor 建议的解决方案,并重新排列了“Features”文件夹中的所有内容。它需要更多的配置,但在我看来更干净。 这篇微软文章也进一步解释了这一点(只需跳过区域内容):
https://msdn.microsoft.com/en-us/magazine/mt763233.aspx
我的结构现在看起来像这样,路由就像一个魅力,控制器名称仍然有意义:


enter image description here

c# .net asp.net-core asp.net-core-mvc asp.net-routing
2个回答
3
投票
HomeController

作为 url 中控制器的默认值。如果您希望 DocumentController 成为默认值,请在 StatrtUp 类中更新它。

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "areas",
        template: "{area:exists}/{controller=Document}/{action=Index}/{id?}"
    );
});

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");

});

请记住,注册代码适用于
所有

现有区域(因为我们在网址模板中有{area:exists}),

不仅仅是文档区域
。这意味着,每当有类似 yourApp\someAreaName 的请求时,框架都会将请求发送到
DocumentController
someAreaName
的索引操作。
您已经将与文档相关的代码组织到了文档区域。现在为什么你需要你的控制器名称是 document ?我觉得,这是重复的。

我个人会将Document区域内的

DocumentController

重命名为

HomeController
,并使用默认的路由注册代码进行区域注册(使用HomeController作为url模板中的默认控制器值)。这样,它将适用于您未来的领域,并且您的代码看起来更干净。
恕我直言,任何区域中的 HomeController 都有意义,而任何区域中的 DocumentController 都会令人困惑。
app.UseMvc(routes => { routes.MapRoute( name: "areas", template: "{area:exists}/{controller=Home}/{action=Index}/{id?}" ); });

ASP.NET Core 6.0 及更高版本:

具有视图的控制器区域 aspnetcore-6.0

app.MapControllerRoute( name: "areas", pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");

这样区域和非区域控制器都将运行。如果您指定区域名称,则该区域的路线将运行,反之亦然。


2
投票

在我的

ASP.NET MVC Core 应用程序模板

中,我利用了功能文件夹,其工作方式有点像区域。 为此,我在

ConfigureServices

方法中添加了以下内容:


serviceCollection.Configure<RazorViewEngineOptions>(options => { options.ViewLocationExpanders.Add(new FeatureLocationExpander()); });

其中 
FeatureLocationExpander

是:


public class FeatureLocationExpander : IViewLocationExpander { public void PopulateValues(ViewLocationExpanderContext context) { // Don't need anything here, but required by the interface } public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) { // The old locations are /Views/{1}/{0}.cshtml and /Views/Shared/{0}.cshtml // where {1} is the controller and {0} is the name of the View // Replace /Views with /Features return new string[] { "/Api/{1}/{0}.cshtml", "/Features/{1}/{0}.cshtml", "/Features/Shared/{0}.cshtml" }; } }

替换
ExpandViewLocations

为您的区域返回的新字符串[]的内容意味着您不必添加路由属性。


但是,这并不能解决您的问题,因为这不是区域的用途。

除非您在

Documents

区域下添加了一个 razor 页面(名为 Index.cshtml),该区域充当文档区域的索引页面。这个 Index.cshtml 可以提供 /Documents/Documents/Index.cshtml 中 Index.cshtml 的所有功能,并具有像您的控制器一样的代码隐藏文件(还记得 ASP.NET Webforms 吗?)的额外好处.

    

© www.soinside.com 2019 - 2024. All rights reserved.