ASP .NET MVC区域注册

时间:2017-01-26 17:49:10

标签: 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 }
        );

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

return Redirect("~/Admin");

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

<li><a href="@Url.RouteUrl("Admin_Categories")">Categories</a></li> ==
<li><a href="~/Admin/Categories">Categories</a></li>

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

祝你好运!

编辑1:

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

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

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

<li><a href="@Url.RouteUrl("Admin_Categories")">Categories</a></li> ==
<li><a href="~/Admin/Categories/Index">Categories</a></li>

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

编辑2

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

[OutputCache(CacheProfile = "OneDayCache")]

但即使清除缓存也无法解决问题。我仍然被重定向到登录控制器索引动作......有什么想法吗?

编辑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" }
    );

我用它来创建路由网址:

@Url.RouteUrl("Admin_Categories")

但仍然无法正常工作。管理员路线在Global.asax中注册,并且没有任何路径可以覆盖这些......

编辑4

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

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

[OutputCache(CacheProfile = "OneDayCache", VaryByCustom = "Url")]
public ActionResult Index(){...}

在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

也许这个VaryByCustom无效。任何想法如何解决它?

4 个答案:

答案 0 :(得分:5)

要进行首次修改:

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

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

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

更好的解决方案:

为什么不简单地删除everthing但是:

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

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

  • FooController - 区域
  • 中查找Admin
  • 致电Bar - 方法就可以了。

然后简单地使用它来生成URL&#39;

@Url.Action("ActionName", "ControllerName", new { Area = "AreaName" })

你可能想要这个:

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

如果你打电话

@Url.Action("Index", "ControllerName", new { Area = "AreaName" })

生成的网址为/AreaName/ControllerName而不是/AreaName/ControllerName/Index

如果你打电话

@Url.Action("Index", "Index", new { Area = "AreaName" })

生成的网址为/AreaName而不是/AreaName/Index/Index

你们应该使用这个区域注册:

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 }
        );
    }
}

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

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

@Url.Action("SomeAction")

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

@Url.Action("SomeAction", "SomeController")

答案 1 :(得分:0)

您是否尝试使用路由属性修饰控制器类?

[Area("Admin")]
[Route("Categories")]
public class CategoriesController : Controller

这对我有一个类似的问题,我使用的是ASPNET Core,你使用的是什么版本的MVC?

答案 2 :(得分:0)

您的路由代码对我来说很好。你确定在登录方法中你是否正确认证?只需尝试从您的&#34;类别&#34;中删除[授权]标记控制器,看看授权是否是问题。

答案 3 :(得分:0)

这是MVC中Area功能的基本实现:

在您的AdminAreaRegistration.cs中:

context.MapRoute(
    "admin_default",
    "admin/{controller}/{action}/{id}",
    new { action = "Index", id = UrlParameter.Optional }
);

使用以下代码装饰您的控制器:

[Area("Admin")]
public class MyController : Controller

另外,请不要忘记在global.asax方法的Application_Start()方法中添加以下代码行(在所有内容之上):

AreaRegistration.RegisterAllAreas();

在视图中使用:

Url.Action("Index", "Categories", new { Area = "Admin" })

这种方式应该可以正常工作。测试!