我对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(...)”时,网址很好。但当我进入页面时,RouteData似乎很糟糕(RouteData未正确恢复)。
看看我的RouteData: 键[0] => “MS_DirectRouteMatches” 键[1] => “控制器”
Values[0] => //A list of only 1 RouteData with my 6 parameters into it...
Values[1] => Produits
如果我删除了我的“自定义路线通知”,一切都很好,但网址非常难过......
有人对问题和解决方案有所了解吗? 谢谢大家的帮助!
编辑: 有关该问题的更多信息。 我有一个语言的“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);
}
感谢您的帮助: - )
编辑: 没有人有解决方案? 再次感谢你!
答案 0 :(得分:8)
对于属性路由,路由值存储在名为“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 :(得分: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}
段变量提供值,那么它将与第二个属性路由映射匹配,您只需解析操作方法中的值