如何在 asp.net mvc 中以编程方式确定路由前缀?

How to determine Route Prefix programmatically in asp.net mvc?

我想为我的 public/anonymous 控制器和视图与 admin/authenticated 控制器和视图提供一些 URL 分离。所以我最终完全使用 Attribute Routing 来更好地控制我的 URL。我希望我的 public URL 以“~/Admin/etc”开头。而我的 public URL 不会有任何这样的前缀。

Public 控制器(几个之一)

[RoutePrefix("Home")]
public class HomeController : Controller
{
    [Route("Index")]
    public ActionResult Index()
    { //etc. }
}

管理控制器(几个之一)

[RoutePrefix("Admin/People")]
public class PeopleController : Controller
{
    [Route("Index")]
    public ActionResult Index()
    { //etc. }
}

这让我可以拥有 public URL,例如:

http://myapp/home/someaction

...和admin/authenticated URL例如:

http://myapp/admin/people/someaction

但现在我想根据用户是在网站的管理部分还是 Public 部分在视图中做一些动态的事情。我怎样才能正确地以编程方式访问它?

我知道我可以做类似的事情

if (Request.Url.LocalPath.StartsWith("/Admin"))

...但感觉 "hacky." 我知道我可以通过

访问控制器和动作名称
HttpContext.Current.Request.RequestContext.RouteData.Values

...但是 "admin" 部分没有反映在那里,因为它只是一个路由前缀,而不是实际的控制器名称。

所以,基本问题是,如何以编程方式确定当前加载的视图是否在 "admin" 部分下?

你只需要从Controller类型中反射出RoutePrefixAttribute,然后得到它的Prefix值。 Controller 实例在 ViewContext.

上可用

此示例创建了一个方便的 HTML 帮助器,它将所有步骤包装到一个调用中。

using System;
using System.Web.Mvc;

public static class RouteHtmlHelpers
{
    public static string GetRoutePrefix(this HtmlHelper helper)
    {
        // Get the controller type
        var controllerType = helper.ViewContext.Controller.GetType();

        // Get the RoutePrefix Attribute
        var routePrefixAttribute = (RoutePrefixAttribute)Attribute.GetCustomAttribute(
            controllerType, typeof(RoutePrefixAttribute));

        // Return the prefix that is defined
        return routePrefixAttribute.Prefix;
    }
}

那么在你看来,你只需要调用扩展方法获取RoutePrefixAttribute的值即可。

@Html.GetRoutePrefix() // Returns "Admin/People"