ASP.NET MVC5路由注释MS_DirectRouteMatches

本文关键字:MS DirectRouteMatches 注释 路由 NET MVC5 ASP | 更新日期: 2023-09-27 18:21:00

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

我有一个控制器"Prodouits"与这个行动:

[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:Keys[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);
}

感谢您的帮助:-)

编辑:没有人有解决方案?再次感谢!

ASP.NET MVC5路由注释MS_DirectRouteMatches

对于属性路由,路由值存储在名为"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

您需要确保在页面上呈现链接时定义段变量{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}段变量提供值,那么它将与第二个属性路由映射相匹配,您只需在操作方法中解析一个值。