简体   繁体   English

ASP.NET Core 2.1 区域路由不起作用

[英]ASP.NET Core 2.1 Areas routing not working

I have this folder structure for my new Area我的新区域有这个文件夹结构

在此处输入图片说明

This is how I set it up in my startup:这是我在启动时设置它的方式:

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

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

This is how I created my basecontroller这就是我创建基本控制器的方式

namespace App.Areas.Applications.Controllers
{
    [Area("Applications")]
    [Authorize]
    public abstract class ApplicationsBaseController : Controller
    {

    }
}

My ApplicationsController then inherits the BaseController然后我的 ApplicationsController 继承了 BaseController

However, when I set a link like this但是,当我设置这样的链接时

<li class="nav-item"><a asp-area="Applications" asp-controller="Applications" asp-action="Index" class="nav-link">Applications</a></li>

This is the link that shows up in my url https://localhost:44338/Applications?area=Applications and I get a page cannot be found.这是显示在我的 url https://localhost:44338/Applications?area=Applications 中的链接,但我无法找到页面。

What did I miss when setting up my Area?设置我的区域时我错过了什么?

EDIT:编辑:

When I add [Route("Applications/[controller]")] after my [Area("Applications")], I get this error当我在 [Area("Applications")] 之后添加 [Route("Applications/[controller]")] 时,出现此错误

An unhandled exception occurred while processing the request.处理请求时发生未处理的异常。 AmbiguousActionException: Multiple actions matched. AmbiguousActionException: 匹配多个操作。 The following actions matched route data and had all constraints satisfied:以下操作与路线数据匹配并满足所有约束:

App.Areas.Applications.Controllers.ApplicationsController.Index (App) App.Areas.Applications.Controllers.ApplicationsController.Create (App) App.Areas.Applications.Controllers.ApplicationsController.NewRole (App) App.Areas.Applications.Controllers.ApplicationsController.Index (App) App.Areas.Applications.Controllers.ApplicationsController.Create (App) App.Areas.Applications.Controllers.ApplicationsController.NewRole (App)

Put it before the default route... like this把它放在默认路由之前......像这样

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

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

IMO, you should create Controller folder to the specific views. IMO,您应该为特定视图创建Controller文件夹。 Otherwise, it will fail when there are multiple controllers in the Applications area.否则当Applications区域有多个controller时会失败。

Anyway, for returning the views just in Views Folder , try to configure the AreaViewLocationFormats to specify the views search location.无论如何,为了仅返回Views Folder中的Views Folder ,请尝试配置AreaViewLocationFormats以指定视图搜索位置。

        public void ConfigureServices(IServiceCollection services)
    {
        //rest services
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddSessionStateTempDataProvider();
        services.Configure<RazorViewEngineOptions>(o =>
        {
            o.AreaViewLocationFormats.Add("/Areas/{2}/{0}" + RazorViewEngine.ViewExtension);
        });
    }

I realized what the issue was.我意识到问题是什么。 In each controller, I needed to declare [Area="AreaName"] in the top before anything else so that the routing worked.在每个控制器中,我需要先在顶部声明 [Area="AreaName"],以便路由正常工作。

Thank you everyone for your help.感谢大家的帮助。

There is another option which does bring some clarification in terms of meta data of the code:还有另一个选项确实在代码的元数据方面带来了一些澄清:

Using MapAreaRoute extension method in Namespace: Microsoft.AspNetCore.Builder在 Namespace 中使用 MapAreaRoute 扩展方法: Microsoft.AspNetCore.Builder

Here is an example:下面是一个例子:

          routes.MapAreaRoute(
                name: "AdminArea",
                areaName: "Admin",
                template: Admin/{controller=Home}/{action=Index}/{id?}");

It is available from .NET Core 1.0它可以从 .NET Core 1.0 获得

Microsoft documentation 微软文档

you can use simple solation你可以使用简单的隔离

Extension延期

public static class AreaExtension
{
    public static string AreaUrl(this IHtmlHelper helper, string action,  params string[] parameters)
    {
        var viewContext = helper.ViewContext.RouteData.Values;

        string controller = (string)viewContext["controller"],
         area = (string)viewContext["area"];
        return GenerateUrl(action, controller, area, parameters);
    }

    public static string AreaUrl(this IHtmlHelper helper, string action, string controller, params string[] parameters)
    {
        var viewContext = helper.ViewContext.RouteData.Values;

        string area = (string)viewContext["area"];
        return GenerateUrl(action, controller, area, parameters);
    }

    public static string AreaUrl(this IHtmlHelper helper, string action, string controller, string area, params string[] parameters)
        => GenerateUrl(action, controller, area, parameters);

    private static string GenerateUrl(string action, string controller, string area, params string[] parameters)
    {
        if (action == null)
            throw new ArgumentNullException(nameof(controller));
        if (controller == null)
            throw new ArgumentNullException(nameof(action));

        string urlParams = string.Empty;

        if (parameters != null && parameters.Length > 0)
            urlParams = "?" + string.Join("&", parameters);

        return "/" + string.Join("/", area, controller, action) + urlParams;
    }
}

Usage用法

Incluse namespase AreaExtension in _ViewImports.cshtml_ViewImports.cshtml包含命名AreaExtension _ViewImports.cshtml

<li class="nav-item"><a href="@Html.AreaUrl("Index", "Applications","Applications")" class="nav-link">Applications</a></li>

This AreaExtension have 3 overload此 AreaExtension 有 3 个重载

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM