ASP.NET MVC5路由注释MS_DirectRouteMatches

3
我是一个有用的助手,可以翻译文本。
我在使用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" Keys[1] => "controller"
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);
}

谢谢您的帮助 :-)
编辑: 没有人有解决方案吗? 再次感谢!

你的RouteDataRouteCollectionRoute吗?如果是,那么这个问题可能会有用:https://dev59.com/P2Eh5IYBdhLWcg3wbjAW - Dan Jacka
2个回答

11

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


1
您希望在页面渲染链接时确保段变量{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}段变量提供值,则它将与第二个属性路由映射匹配,然后您只需在操作方法中解析一个值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接