2010-11-07 84 views
4

我正在使用spark viewengine,asp.net mvc和.resx文件。使用ASP.NET MVC进行Spark全球化

我想通过我的自定义SessionModel(会话),它是通过Castle.Windsor注册并具有可以由用户设置文化的字符串属性来设置语言...

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

不必为此,每次在每个控制器动作:

public SessionModel SessionModel { get; set; } 

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

用做这种方式的问题是,如果我去到另一页当前文化将翻转回默认语言。

在火花视图我简单的调用,以获得当前文化:

${SR.Home} 

SR.resx包含主页公开条目。

有没有人有一个好主意,如何做到这一点,我应该这样做与ActionFilter?

+0

[如何本地化ASP.NET MVC + Spark应用程序?](http://stackoverflow.com/questions/788635/how-to-localize-asp-net-mvc-spark-application) – bzlm 2010-11-07 17:40:21

+0

他谈论的样本究竟是什么问题,它将信息保存在一个普通的ASP.NET会话中,并且必须在每个额外的控制器上请求它。 – Andrew 2010-11-07 18:08:15

回答

1

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

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

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

+0

我一直在摆弄这样的事情,问题是我不能注入温莎会议,我已经进入了IActionFilter。然后提出了如何让我的语言保持最新的问题......现在我唯一能做的就是使用HTTPContext.Currrent.Session,这真的很烦人。然而,也许我看错了,你对FetchCultureFromContext有什么想法? – Andrew 2010-11-07 18:05:04

+0

是的,你不能使用DI开箱即用。有[解决方法](http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/05/03/dependency-injection-in-asp-net-mvc-filters.aspx)。这[可能](http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html)虽然在ASP.NET MVC 3中。 – 2010-11-07 18:07:56

+0

我结束了使用:http:/ /weblogs.asp.net/psteele/archive/2009/11/04/using-windsor-to-inject-dependencies-into-asp-net-mvc-actionfilters.aspx将我的会话注入到一个自定义的ActionFilterAttribute中,并且工作。谢谢你的帮助。 – Andrew 2010-11-09 14:47:45

0

对于这个问题,如果您使用Spark View Engine已经解决了这个问题,有一个更好的和可扩展的(从灵活性的角度来看)解决方案。

看看sample solution here in the code base是一个关于如何使用Spark进行国际化或全球化的极好例子。绝对不需要用ActionFilter开始做一些奇特的事情 - 而且这种方法在MVC2和MVC3中起作用,如果这是您未来的计划,则可以轻松进行迁移。

更新

在回答您的其他问题就在Spark的代码库,我认为有剥皮那猫的一些方法的样本。一种方法是将文化作为会话的一部分,但在过去那些我们不想要的项目中,我们做了许多网站已经做的事情 - 我们通过确保文化作为参数包含在文化数据中包含在URL:

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

这种东西结合我上面提到的给你的自由,只是花的时间集中于你的.resx文件,而不是所有的时间搞清楚的文化和路由星火模块手动。

事实上,您在同一个视图文件夹中有Index.sparkIndex.fr.spark,这意味着剩下的事情会得到照顾。

希望有帮助!
所有最好的,
罗布

+0

看到,下面的回应,很适合这个小盒子。 – Andrew 2010-11-09 01:08:14

+0

我已将更新添加到我的答案中。希望我覆盖它? – RobertTheGrey 2010-11-15 18:22:31

0

我想我失去了一些东西。这是我想要避免的(应用程序。CS)火花塞样品里面,我已经有一个自定义会话,它并不需要管理其他,只是为了“文化”:

示例代码:

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或创建一个基本控制器。