使用 ASP.NET MVC 进行 Spark 全球化

发布于 2024-09-30 19:35:17 字数 744 浏览 13 评论 0原文

我正在使用 Spark ViewEngine、asp.net mvc 和 .resx 文件。

我想通过我的自定义 SessionModel (会话)设置一种语言,该模型通过 Castle.Windsor 注册,并具有可由用户设置的 Culture 字符串属性...

我需要当前语言在每个视图上保留,而不必不断设置当前的 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}

SR.resx 包含 Home 的公共条目。

有谁知道如何执行此操作,我应该使用 ActionFilter 执行此操作吗?

I am using the spark viewengine, asp.net mvc, and .resx files.

I want to set a language through my custom SessionModel (Session) which is registered through Castle.Windsor and has a string property of Culture which can be set by the user...

I need the current language to persist on every view, without having to constantly set the current UICulture.

Not having to do this everytime in each Controller Action:

    public SessionModel SessionModel { get; set; }

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

The problem with doing it this way, is if I go onto another page the current culture will flip back to the default language.

On the spark view I simply call, to obtain the current Culture:

${SR.Home}

SR.resx contains a public entry for Home.

Does anyone have a good idea of how to do this, should I do this with an ActionFilter?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

美胚控场 2024-10-07 19:35:17

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

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

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

Action filter seems like a good idea:

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

and then decorate your base controller with this attribute.

听不够的曲调 2024-10-07 19:35:17

我想我错过了一些东西。这就是我在 Spark 示例中试图避免的(Application.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 Index 内部进行调用,以将当前区域性从会话中拉出:

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

I guess I am missing something. This is what I am trying to avoid (Application.cs) inside of the spark samples, I already have a custom session, it don't need to manage another, just for "culture":

the sample code:

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

Also after its done, how do I load the current culture for every page I have, I would have to make the call inside of HomeController Index to pull the current culture out of the session:

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

Which the only way I can come up with right now is by either creating a custom ActionFilter or creating a base Controller.

单身狗的梦 2024-10-07 19:35:17

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

查看代码库中的示例解决方案 有关如何使用 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 ,这意味着其余的事情都会为您处理好。

希望有帮助!
祝一切顺利,

There is a much better and scalable (from a flexibility point of view) solution to this problem which has been solved if you're using the Spark View Engine.

Have a look at the sample solution here in the code base for an excellent example of how to do Internationalization or Globalization with Spark. There is absolutely no need to start doing fancy things with your ActionFilters - and this method works in MVC2 and MVC3 to allow for an easy migration if that's your future plan.

Update

In response to your other question regarding the sample in the Spark code base I think there are a few ways of skinning that cat. One way would be to keep the culture as part of the session, but in past projects where we didn't want that, we did what many website already do - we included the culture as a parameter in the route data by making sure it is included in the URL:

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

This kind of thing in combination with the Spark module I mentioned above gives you the freedom to just spend time focussing on your .resx files instead of all your time figuring out the culture and routing manually.

The fact that you have an Index.spark and an Index.fr.spark in the same views folder means the rest gets taken care of for you.

Hope that helps!
All the best,
Rob

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文