使用BaseClass实现的属性路由:已严格列出但仍然失败

时间:2014-11-11 10:56:30

标签: asp.net-mvc-5 asp.net-mvc-routing

我在控制器类上设置属性路由,该控制器类继承了我处理I18N文化集/选择逻辑的基类(如文章ASP.NET MVC 5 Internationalization中所述)但该过程失败,尽管路径似乎是设置正确。

[RoutePrefix("{culture}")]
public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return View();
    }
    [Route("Hakkimda")]
    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";

        return View();
    }

Glimpse Routing Debug Screen

当我尝试链接时,我会在地址栏上看到浏览器上的灰色死屏:

http://localhost:53530/tr-tr/Hakkimda?MS_DirectRouteMatches=System.Collections.Generic.List%601%5BSystem.Web.Routing.RouteData%5D

我认为问题在于基本控制器实现基于BeginExecuteCore重载的I18N逻辑的方式。

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);
}

BeginExecuteCore和路由的执行优先级可能存在一些不匹配,但我对两者的了解都不足以解决它。

我已经看过这篇文章(What’s New in ASP.NET MVC 5.2 : Attribute routing improvements)但是示例提供的内容有点不同,因为它是新的,网上没有其他例子。

2 个答案:

答案 0 :(得分:2)

先生的答案将阻止你在地址栏中收到垃圾,但它也会阻止语言的变化。

从MVC5更改为MVC5.2后,我遇到了这个问题 This answer says it is a Microsoft issue

解决方法是查看路由数据是否在嵌套路由密钥

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

然后就行了。

答案 1 :(得分:0)

删除此代码

  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);                
}