ASP .NET MVC区域注册

Ash*_*v3r 4 c# asp.net asp.net-mvc routes area

我的"管理"区域注册没有什么问题,它存储在"管理"区域文件夹内的AdminAreaRegistration.cs中.我的路线看起来像这样:

        context.MapRoute(
            "Admin_News",
            "Admin/News",
            new { controller = "News", action = "Index" }
        );

        context.MapRoute(
            "Admin_Pages",
            "Admin/Pages",
            new { controller = "Pages", action = "Index" }
        );

        context.MapRoute(
            "Admin_Galleries",
            "Admin/Galleries",
            new { controller = "Galleries", action = "Index" }
        );

        context.MapRoute(
            "Admin_Categories",
            "Admin/Categories",
            new { controller = "Categories", action = "Index" }
        );

        context.MapRoute(
            "Admin_Products",
            "Admin/Products",
            new { controller = "Products", action = "Index" }
        );

        context.MapRoute(
            "Admin_Files",
            "Admin/Files",
            new { controller = "Files", action = "Index" }
        );

        context.MapRoute(
            "Admin_Orders",
            "Admin/Orders",
            new { controller = "Orders", action = "Index" }
        );

        context.MapRoute(
            "Admin_Codes",
            "Admin/Codes",
            new { controller = "Codes", action = "Index" }
        );

        context.MapRoute(
            "Admin_Login",
            "Admin/Login",
            new { controller = "Login", action = "Index" }
        );

        context.MapRoute(
            "Admin_Panel",
            "Admin",
            new { controller = "Index", action = "Index" }
        );

        context.MapRoute(
            "Admin_Default",
            "Admin/{controller}/{action}/{param}",
            new { param = UrlParameter.Optional }
        );
Run Code Online (Sandbox Code Playgroud)

问题是:当我登录后,我使用

return Redirect("~/Admin");
Run Code Online (Sandbox Code Playgroud)

一切都很好,直到我想点击链接(生成良好)

<li><a href="@Url.RouteUrl("Admin_Categories")">Categories</a></li> ==
<li><a href="~/Admin/Categories">Categories</a></li>
Run Code Online (Sandbox Code Playgroud)

然后我想重定向到类别控制器的索引操作,而是重定向到登录控制器的索引操作.任何想法为什么会这样发生?

最好的祝福!

编辑1:

好吧,我已将Admin_Categories路线改为此路线:

context.MapRoute(
    "Admin_Categories",
    "Admin/Categories/{action}",
     new { controller = "Categories" }
);
Run Code Online (Sandbox Code Playgroud)

它似乎工作,但现在url正在生成动作名称,在Index动作的情况下我不会这样:

<li><a href="@Url.RouteUrl("Admin_Categories")">Categories</a></li> ==
<li><a href="~/Admin/Categories/Index">Categories</a></li>
Run Code Online (Sandbox Code Playgroud)

如何从网址中删除操作名称?

编辑2

好吧,所以不知何故,我的浏览器缓存了类别控制器索引操作视图作为登录控制器索引操作视图.清除浏览器缓存后问题解决了一段时间.我在所有视图中使用了以下缓存属性(仅对需要参数的视图使用了VarByParam):

[OutputCache(CacheProfile = "OneDayCache")]
Run Code Online (Sandbox Code Playgroud)

但即使清除缓存也无法解决问题.我仍然被重定向到Login controller Index action ...有什么想法吗?

编辑3

我使用了那些AreaRoutes:

context.MapRoute(
    "Admin_Categories",
    "Admin/Categories",
    new { controller = "Categories", action = "Index", param = UrlParameter.Optional },
    new[] { "AMBIT_CMS_MVC.Areas.Admin.Controllers" }
);

context.MapRoute(
    "Admin_Default",
    "Admin/{controller}/{action}/{param}",
    new { controller = "Index", action = "Index", param = UrlParameter.Optional },
    new[] { "AMBIT_CMS_MVC.Areas.Admin.Controllers" }
    );
Run Code Online (Sandbox Code Playgroud)

我用它来创建路由网址:

@Url.RouteUrl("Admin_Categories")
Run Code Online (Sandbox Code Playgroud)

但仍然没有按预期工作.管理员路线在Global.asax中注册,并且没有任何路径可以覆盖这些路线......

编辑4

我发现我的问题是缓存.Chrome以某种方式将我的/管理员/类别位置缓存为/ Admin/Login,因此当我点击url/Admin/Categories缓存时将其重定向到/ Admin/Login.

我使用OutputCache属性,但似乎无法正常工作.

[OutputCache(CacheProfile = "OneDayCache", VaryByCustom = "Url")]
public ActionResult Index(){...}
Run Code Online (Sandbox Code Playgroud)

在Global.asax中设置VaryByCustom:

public override string GetVaryByCustomString(HttpContext context, string arg)
    {
        if (arg.Equals("Url"))
        {
            string url = !string.IsNullOrWhiteSpace(context.Request.Url.AbsoluteUri) ? context.Request.Url.AbsoluteUri : string.Empty;
            return "Url=" + url;
        }
        return base.GetVaryByCustomString(context, arg);
    }

http://localhost:50945/Admin/Categories
HTTP/1.1 302 Found
Cache-Control: private, max-age=86400
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2017 20:24:19 GMT
Last-Modified: Wed, 08 Feb 2017 20:24:19 GMT
Location: /Admin/Login
Server: Microsoft-IIS/10.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?TTpcUHJvamVrdHlcQU1CSVQtQ01TLU1WQ1xBTUJJVCBDTVMgTVZDXEFkbWluXENhdGVnb3JpZXM=?=
X-Powered-By: ASP.NET
Date: Wed, 08 Feb 2017 20:24:19 GMT
Content-Length: 439
Run Code Online (Sandbox Code Playgroud)

也许这个VaryByCustom不起作用.任何想法如何解决它?

Chr*_*rdt 5

第一次编辑:

第三个参数注册默认值.您缺少默认值action.

将您的路线更改为此,它将起作用:

context.MapRoute(
    "Admin_Categories",
    "Admin/Categories/{action}",
     new { controller = "Categories", action = "Index" }
);
Run Code Online (Sandbox Code Playgroud)

更好的解决方案:

为什么不简单删除everthing但这个:

context.MapRoute(
    "Admin_Default",
    "Admin/{controller}/{action}/{param}",
    new { param = UrlParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)

这意味着例如请求/Admin/Foo/Bar得到解决,如下所示:

  • FooControllerAdmin-Area中查找
  • 打电话 - Bar方法就可以了.

然后简单地使用它来生成URL

@Url.Action("ActionName", "ControllerName", new { Area = "AreaName" })
Run Code Online (Sandbox Code Playgroud)

你可能想要这个:

context.MapRoute(
    "Admin_Default",
    "Admin/{controller}/{action}/{param}",
    new { controller = "Index", action = "Index", id = UrlParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)

如果你打电话

@Url.Action("Index", "ControllerName", new { Area = "AreaName" })
Run Code Online (Sandbox Code Playgroud)

生成的Url将/AreaName/ControllerName代替/AreaName/ControllerName/Index.

如果你打电话

@Url.Action("Index", "Index", new { Area = "AreaName" })
Run Code Online (Sandbox Code Playgroud)

生成的Url将/AreaName代替/AreaName/Index/Index.

所有这些你应该使用这个AreaRegistration:

public class AdminAreaRegistration : AreaRegistration 
{
    public override string AreaName 
    {
        get 
        {
            return "Admin";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context) 
    {
        context.MapRoute(
            "Admin_default",
            "Admin/{controller}/{action}/{id}",
            new { controller = "Index", action = "Index", id = UrlParameter.Optional }
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你真的需要它,只创建一个新的路线.然后不要忘记在第三个参数中设置默认值MapRoute.

另请注意,如果您已经在同一个控制器的视图中,则可以编写动作:

@Url.Action("SomeAction")
Run Code Online (Sandbox Code Playgroud)

如果你在同一区域的视图中,但想要调用另一个控制器,你可以这样写:

@Url.Action("SomeAction", "SomeController")
Run Code Online (Sandbox Code Playgroud)