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

时间:2017-10-12 12:32:09

标签: c# .net asp.net-core asp.net-core-mvc asp.net-routing

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

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

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

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

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

修改
根据Shyju和Jamie Taylor的建议,我选择了HomeControllers。 (谢谢你们的快速解答和解释)

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

对我来说,拥有如此多的HomeControllers和索引文件仍然有点令人失望。导航代码不再容易:
enter image description here

EDIT2:
在对所有那些家庭控制器过于恼火之后,我选择了Jamie Taylor建议的解决方案并重新安排了 Features 文件夹中的所有内容。它需要更多的配置,但在我看来更清洁。
在这篇微软文章中也进一步解释了(只是跳过区域内容):
https://msdn.microsoft.com/en-us/magazine/mt763233.aspx

我的结构现在看起来像这样,路由就像魅力一样,控制器名称仍然有意义:
enter image description here

2 个答案:

答案 0 :(得分:2)

区域的默认路由注册使用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时,框架都会将请求发送到DocumentControllersomeAreaName的索引操作。

您已将与文档相关的代码组织到“文档”区域。现在为什么你需要你的控制器名称作为文件?我觉得,这是重复的。

我个人将文档区域内的DocumentController重命名为HomeController,并使用默认路径注册代码进行区域注册(使用HomeController作为url模板中的默认控制器值)。这样,它将适用于您未来的领域,您的代码看起来更干净。 恕我直言,任何区域的HomeController都有意义,任何区域的DocumentController都会让人困惑。

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

答案 1 :(得分:2)

我不确定这是什么领域。也许你应该重新思考你的架构。

在我的ASP.NET MVC Core application template中,我使用了功能文件夹,其功能与区域类似。

为此,我在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区域下添加了一个剃刀页面(名为Index.cshtml),该区域充当“文档”区域的索引页面。这个Index.cshtml可以在/Documents/Documents/Index.cshtml中提供Index.cshtml的所有功能,还有一个类似于代码隐藏的文件(还记得ASP.NET webforms吗?),它就像你的控制器一样