【问题标题】:Is it possible for two areas to share the same route and still both be reachable?两个区域是否有可能共享相同的路线并且仍然可以到达?
【发布时间】:2014-02-14 16:05:36
【问题描述】:

我有两个区域注册路由,如下所示:

“网站”区域:

context.MapRoute(
    "Landing Controllers",
    "{controller}/{action}",
    new { controller = "Home", action = "Index" }
);

“移动”区域:

context.MapRoute(
    "Mobile Defaults",
    "{controller}/{action}",
    new { controller = "MobileHome", action = "Index" },
    new { controller = "MobileHome", action = "Index" }
);

默认情况下,当尝试转到根 URL / 时,将始终采用这些路由中的一个或另一个。但是假设我们用自定义的AuthorizeAttribute 修饰了我们的控制器操作,其中OnAuthorization 方法被覆盖以在适当的时候将用户重定向到正确的控制器,如下所示。 (想法来自伟大的blog post。)

public class MobileRedirectAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var result = // Logic to generate the ActionResult that conditionally
                     // takes us to the other route goes here.

        filterContext.Result = result;
    }
}

我尝试使用新的RedirectResultRedirectToRouteResult,由于路由冲突,这两种方法都无法正常工作。有没有办法将AuthorizationContext.Result 设置为一个可以将我们带到我们当前未执行的操作的值? (作为最后的手段,我可​​以在移动路由前加上某种命名空间变量,但我想避免走这条路。)


我的问题也可以通过查看维基百科的桌面/移动路由来总结。他们的两个站点,http://en.m.wikipedia.org/wiki/Main_Pagehttp://en.wikipedia.org/wiki/Main_Page 也共享相同的路由,但是,根据您所处的模式,返回的结果非常不同。

是否可以在 MVC 项目中设置 Wikipedia 的路由,其中​​每个环境(移动/桌面)都注册在自己的区域中?

【问题讨论】:

  • 您真的需要为移动设备和非移动设备使用不同的控制器吗?还是只是单独的视图就足够了?
  • @EugeneBrianOng 是的,它们的功能之间的差异足以保证单独的控制器。

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


【解决方案1】:

一位同事用自定义IRouteConstraint 引导我找到了一个很有前途的解决方案。

public class HelloWorldConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route,
        string parameterName, RouteValueDictionary values,
        RouteDirection routeDirection)
    {
        // Determine whether to accept the route for this request.
        var browser = BrowserDetector.Parse(httpContext.Request.UserAgent);
        if (browser == BrowserPlatform.Mobile)
        {
            return true;
        }

        return false;
    }
}

我的路由声明现在如下所示,其中路由约束附加到随机选择的路由参数。

context.MapRouteLowercase(
    "Mobile Defaults",
    "{controller}/{action}",
    new { controller = "MobileHome", action = "Index" },
    // In this case, it's not so much necessary to attach the constraint to
    // a particular route parameter as it is important to be able to inspect
    // the HttpContextBase provided by the IRouteConstraint.
    new {
        controller = new HelloWorldConstraint()
    }
);

【讨论】:

    【解决方案2】:

    不适用于标准 MVC 路由。您可能可以使用 MVC 5 中或通过 nuget 包 AttributeRouting 提供的属性路由。

    【讨论】:

    • 感谢您的通知!我不知道属性路由在 MVC5 中可用,绝对值得一试。
    • 它基于 AttributeRouting nuget 包,但不支持该包的所有功能。使用 MVC5,您基本上只需获得 RoutePrefix 来指定控制器本身的部分路由,并获得 Route 来指定每个操作的路由。 AttributeRouting 有许多其他功能,例如对区域、子域等的支持。我自己没有尝试过,但是如果您需要额外的功能,您仍然应该能够在 MVC 5 之上安装 AttributeRouting(nuget 包)。
    猜你喜欢
    • 1970-01-01
    • 2016-03-10
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多