【问题标题】:ASP.Net MVC 4 w/ AttributeRouting and multiple RoutePrefix attributesASP.Net MVC 4 w/ AttributeRouting 和多个 RoutePrefix 属性
【发布时间】:2014-10-23 13:54:52
【问题描述】:

TL;DR

我需要一种方法来根据我的 MVC 应用程序中用户的属性生成 URL 时以编程方式选择选择哪个 RoutePrefix

不是 TL;DR

我有一个 MVC 4 应用程序(带有 AttributeRouting NuGet 包)

由于托管环境的要求,我的很多操作都必须有两条路由,以便托管环境可以具有不同的访问权限。

我通过用[RoutePrefix("full")] [RoutePrefix("lite)] 装饰我的控制器来解决这个问题。它允许通过 /full/{action} 和 /lite/{action} 访问每个操作方法。

这很好用。

[RoutePrefix("full")]
[RoutePrefix("lite")]
public class ResultsController : BaseController
{
    // Can be accessed via /full/results/your-results and /lite/results/your-results and 
    [Route("results/your-results")]              
    public async Task<ActionResult> All()
    {
    }

}

但是,每个用户只能在其 url 中使用 full 或 lite,这取决于该用户的某些属性。

很明显,当我使用RedirectToAction()@Html.ActionLink() 时,它只会选择第一个可用路由,而不会保留“正确”前缀。

我想我可以覆盖RedirectToAction() 方法以及添加我自己版本的@Html.ActionLink() 方法。

这会起作用,但它会涉及一些讨厌的代码来生成 URL,因为我得到的只是一个代表动作和控制器的字符串,而不是反映的类型。也可能有路由属性,例如我的示例,所以我将不得不复制大量内置代码的 MVC。

我要解决的问题有更好的解决方案吗?

【问题讨论】:

  • 我很困惑,这些路由实际提供的内容是否有任何区别,或者只是 url 看起来不同但返回给用户的数据相同?您是否使用 url 来检查身份验证?
  • URL 需要看起来不同,但返回给用户的数据相同。对于两种不同类型的用户有一个外部身份验证系统,要求“lite”用户的所有 URL 都以 /lite/ 为前缀,“full”用户的所有 URL 都以“full”为前缀
  • 我不确定它是否有效(从我的平板电脑 atm 打字),但您可以尝试将您的 ResultsController 子类化为 FullResultsControllerLiteResultsController,并应用相对的 RoutePrefix两者的属性。无需复制任何代码。
  • 我希望这不是唯一正在发生的身份验证,否则用户从lite 更改为full 将非常容易(尽管看起来毫无意义)。您可能想了解如何使用重写规则或类似您提到的东西,用您自己的方法包装路由更改方法,在创建路由后进行替换。
  • @John 不,有外部身份验证。只是为了让它起作用,它需要按照我提到的那样构建我的 URL

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


【解决方案1】:

怎么样:

[RoutePrefix("{version:regex(^full|lite$)}")]

然后,当您创建链接时:

@Url.RouteUrl("SomeRoute", new { version = "full" })

或者

@Url.RouteUrl("SomeRoute", new { version = "lite" })

您甚至可以执行以下操作来保留已设置的内容:

@Url.RouteUrl("SomeRoute", new { version = Request["version"] })

【讨论】:

    【解决方案2】:

    我最终找到了解决方案

    我刚刚覆盖了默认路由以包含它。 ASP.Net 自动保留 usertype 值并在重新生成路由时将其放回

    const string userTypeRegex = "^(full|lite)$";
    routes.Add("Default", new Route("{usertype}/{controller}/{action}/{id}",
                new { controller = "Sessions", action = "Login", id = UrlParameter.Optional }, new { usertype = userTypeRegex }));
    

    我发现这不适用于RouteRoutePrefix 属性,因此我不得不将它们全部删除。在这些情况下强迫我添加特定路线

    routes.Add("Profile-Simple", new Route("{usertype}/profile/simple",
                new { controller = "ProfileSimple", action = "Index" }, new { usertype = userTypeRegex }));
    

    我认为我的RouteConfig 文件中的六个硬编码路由是一个更好的解决方案,而不是必须手动将值添加到我生成 URL 的每个位置(如在 Chris 的解决方案中)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-25
      • 1970-01-01
      相关资源
      最近更新 更多