代码之家  ›  专栏  ›  技术社区  ›  Andrew

用ASP.NET MVC激发全球化

  •  4
  • Andrew  · 技术社区  · 15 年前

    我正在使用spark viewengine、asp.net mvc和.resx文件。

    我需要当前的语言坚持每一个观点,而不必不断地设置当前的UICulture。

    不必每次在控制器操作时都这样做:

        public SessionModel SessionModel { get; set; }
    
        public ActionResult Index()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(SessionModel.Culture);
            Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
        }
    

    这样做的问题是,如果我转到另一个页面,当前区域性将返回到默认语言。

    在spark视图中,我简单地调用,以获得当前的文化:

    ${SR.Home}
    

    有人知道怎么做吗,我应该用ActionFilter来做吗?

    3 回复  |  直到 15 年前
        1
  •  1
  •   Darin Dimitrov    15 年前

    动作过滤器似乎是个好主意:

    public class SetCultureActionFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            CultureInfo culture = FetchCultureFromContext(filterContext);
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;
            base.OnActionExecuting(filterContext);
        }
    
        private CultureInfo FetchCultureFromContext(ActionExecutingContext filterContext)
        {
            throw new NotImplementedException();
        }
    }
    

    然后用这个属性装饰你的基本控制器。

        2
  •  0
  •   Andrew    15 年前

    我想我少了点什么。这是我试图避免的(Application.cs)在spark示例中,我已经有了一个自定义会话,它不需要管理另一个会话,只需要“culture”:

        public static string GetSessionCulture(ControllerContext controllerContext)
        {
            return Convert.ToString(controllerContext.HttpContext.Session["culture"]);
        }
    
        public static void SetSessionCulture(ControllerContext controllerContext, string culture)
        {
            controllerContext.HttpContext.Session["culture"] = culture;
        }
    

    同样,在它完成之后,我如何为我拥有的每个页面加载当前区域性,我将不得不在HomeController索引内调用以将当前区域性从会话中拉出:

        public object Index()
        {
            var user = new UserInfo
                                   {
                                       Name = "Frankie",
                                       Culture = Application.GetSessionCulture(ControllerContext)
                                   };
    
            try
            {
                Thread.CurrentThread.CurrentCulture = 
                    CultureInfo.CreateSpecificCulture(user.Culture);
            }
            catch
            {
                Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");
            }
            Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
    
            ViewData["user"] = user;
            return View();
        }
    

    我现在唯一能想到的方法就是创建一个自定义的ActionFilter或者创建一个基本控制器。

        3
  •  0
  •   RobertTheGrey    15 年前

    有一个更好的和可扩展的(从灵活性的角度)解决这个问题,如果你正在使用SkView引擎,已经解决了这个问题。

    sample solution here in the code base 一个很好的例子来说明如何用Spark实现国际化或全球化。完全不需要开始用ActionFilters做一些花哨的事情——而且这个方法在MVC2和MVC3中工作,如果这是您的未来计划,那么它允许轻松的迁移。

    更新

    在回答您关于Spark代码库中的示例的另一个问题时,我认为有几种方法可以对这只猫进行蒙皮。一种方法是将区域性保留为会话的一部分,但在过去我们不希望这样做的项目中,我们做了许多网站已经做的事情-我们通过确保将区域性包含在URL中,将其作为参数包含在路由数据中:

    routes.Add(new Route("{culture}/{controller}/{action}/{id}", new MvcRouteHandler())
       {
          Defaults = new RouteValueDictionary(
             new { culture="en-us" action="Index", id="" }),
       });
    

    这类事情与我前面提到的Spark模块结合起来,让您可以自由地将时间集中在.resx文件上,而不必花费所有时间手动计算区域性和路由。

    事实上你有一个 Index.spark Index.fr.spark 在同一个views文件夹中意味着剩下的部分将由您来处理。


    一切顺利,
    抢劫