在一个位置将所有视图的参数从路由读取到ViewBag中



我有一个正在运行的MVC3项目,我需要添加string languageId作为路由中的第一个参数,如下所示:

routes.MapRoute(
    "ProductRoute",
    "{languageId}/products/{slug}", 
    new { controller = "Home", action = "Product"} 
);

languageId仅用于渲染视图,因此我希望避免将其作为命名参数添加到我的所有操作中。理想情况下,我应该能够在viewbag中添加一次,在所有从属视图中使用它(所有视图共享同一主页面)。

我可以覆盖控制器中的Initialize,读取路由参数并存储它,但之后我需要在每个操作中将它注入到视图中,或者有其他方法吗?

我假设这是为了项目的国际化?

这是一篇很好的博客文章(由两部分组成的系列文章),它帮助我完成了我目前正在进行的一个项目:http://afana.me/post/aspnet-mvc-internationalization.aspx

Darin Dimitrov的另一篇很棒的帖子应该会回答你的问题:ASP.NET MVC语言更改链接

当我忽略从路由参数中获取语言ID值的问题,并专注于您自己关于如何在请求管道的开头存储一些信息的评论时,可能的解决方案如下。请注意,它"快速且可能很脏",可能不是应用程序设计方面的最佳解决方案。

在global.asax:

public MvcApplication()  // Constructor
{
    this.BeginRequest += new EventHandler(MvcApplication_BeginRequest);
}
void MvcApplication_BeginRequest(object sender, EventArgs e)
{
    Context.Items["LanguageId"] = 2;  // Store your language ID value here.
}

在一个(在我的情况下Razor)的观点:

@if ((int)HttpContext.Current.Items["LanguageId"] == 2)
{
    // Do something with the language ID.
}

或者访问控制器(或ControllerBase类)中的HttpContext.Items["LanguageId"]并将该项存储在ViewBag中。

感谢您的回答。我最终做了以下事情:

我创建了一个BaseController,所有其他控制器都继承它,并覆盖了它的Initialize method,如下所示:

    protected override void Initialize(System.Web.Routing.RequestContext requestContext)
    {
        base.Initialize(requestContext);
        ViewBag.LanguageId = requestContext.RouteData.Values["languageId"] ?? NamedConsts.DefaultLangId;
    }

NamedConsts只是我的类,它保存应用程序静态数据,就像默认语言一样。我现在可以在任何下游使用ViewBag.LanguageId。唯一的问题是ViewBag是动态的,因此我必须到处投射ViewBag.LanguageIdstring。如果有人有更好的解决方案来满足需求,我很乐意接受。

最新更新