【问题标题】:ASP.NET MVC5 Route Annotation MS_DirectRouteMatchesASP.NET MVC5 路由注释 MS_DirectRouteMatches
【发布时间】:2014-11-01 20:49:14
【问题描述】:

我对 ASP.NET 和 MVC5 有一个小问题(我从 MVC.NET 开始)。 直到昨天,一切都很好!但是今天,我不知道为什么,“自定义路由注释”有问题。

我有一个具有此操作的控制器“Produits”:

[Route("{culture}/Produits/{nom_groupe}/{nom}-{id}")]
public ActionResult Detail(string nom_groupe, string nom, string id)
{
    // ...   
    return View();
}

在我看来,当我调用“Url.Action(...)”时,URL 是好的。但是当我进入页面时,RouteData 似乎是坏的(RouteData 没有正确恢复)。

看看我的 RouteData : 键[0] => "MS_DirectRouteMatches" 键[1] => “控制器”

Values[0] => //A list of only 1 RouteData with my 6 parameters into it...
Values[1] => Produits

如果我删除我的“自定义路由注释”,一切正常,但 URL 非常难过......

有人知道问题和解决方案吗? 感谢大家的帮助!

编辑: 有关该问题的更多信息。 我有一个语言的“BaseController”。我重写了“BeginExecuteCore”方法。 有代码:

protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
    string cultureName = RouteData.Values["culture"] as string;

    // Attempt to read the culture cookie from Request
    if (cultureName == null)
        cultureName = Request.UserLanguages != null && Request.UserLanguages.Length > 0 ? Request.UserLanguages[0] : null; // obtain it from HTTP header AcceptLanguages

    // Validate culture name
    cultureName = CultureHelper.GetImplementedCulture(cultureName); // This is safe


    if (RouteData.Values["culture"] as string != cultureName)
    {

        // Force a valid culture in the URL
        RouteData.Values["culture"] = cultureName.ToLowerInvariant(); // lower case too

        // Redirect user
        Response.RedirectToRoute(RouteData.Values);
    }


    // Modify current thread's cultures            
    Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
    Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

    return base.BeginExecuteCore(callback, state);
}

感谢您的帮助:-)

编辑: 没人有解决办法吗? 再次感谢!

【问题讨论】:

标签: c# asp.net asp.net-mvc routes


【解决方案1】:

对于属性路由,路由值存储在名为“MS_DirectRouteMatches”的嵌套路由键中(正如您自己发现的那样)。

以下是使用属性路由时如何使 RouteData 按预期工作:

protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
    // DEMO: now cultureNameTest will be null
    string cultureNameTest = RouteData.Values["culture"] as string; 

    var routeData = RouteData;
    if (routeData.Values.ContainsKey("MS_DirectRouteMatches"))
    {
        routeData = ((IEnumerable<System.Web.Routing.RouteData>)RouteData.Values["MS_DirectRouteMatches"]).First();
    }

    // Now cultureName will not be null
    cultureName = routeData.Values["culture"] as string; 

我在这里找到了这个解决方案:https://stackoverflow.com/a/29083492/533460

【讨论】:

    【解决方案2】:

    您要确保在页面上呈现链接时定义了段变量{culture}。我怀疑这就是生成操作链接的调用可能失败的原因

    MVC 路由系统在生成传出路由 url 时,始终确保它可以为路由 URL 中的每个必需的段变量建立一个值,以使路由匹配。如果您不能始终保证这一点,一种方法可能是使用 {culture} 段变量的默认值重新设计链接,如下所示:

    [Route("{culture=en-us}/Produits/{nom_groupe}/{nom}-{id}")]

    您可以尝试的另一个选项是在同一个操作方法上定义 2 条路由,如下所示:

            [Route("{culture}/Produits/{nom_groupe}/{nom}-{id}")]
            [Route("Produits/{nom_groupe}/{nom}-{id}")]
            public ActionResult Detail(string nom_groupe, string nom, string id, string culture = null)
            {
               if(string.IsNullOrWhitespace(culture))    {
                  culture = //Resolve a value for culture here
                }
                // ...   
                return View();
            }
    

    通过这种方式,您将获得两全其美,如果您无法为 {culture} 段变量提供值,那么它将与第二个属性路由映射匹配,您只需在操作方法中解析一个值。

    【讨论】:

      猜你喜欢
      • 2015-09-20
      • 1970-01-01
      • 2015-05-03
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多