Spark Globalization с ASP.NET MVC - PullRequest
       30

Spark Globalization с ASP.NET MVC

4 голосов
/ 07 ноября 2010

Я использую файлы spark viewengine, asp.net mvc и .resx.

Я хочу установить язык через мой пользовательский SessionModel (Session), который зарегистрирован через 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;
    }

Проблема в том, что если я перейду на другую страницу, текущая культура вернется к языку по умолчанию.

В виде искры я просто звоню, чтобы получить текущую Культуру:

${SR.Home}

SR.resx содержит публичную запись для Home.

Кто-нибудь имеет хорошее представление о том, как это сделать, я должен сделать это с помощью ActionFilter?

Ответы [ 3 ]

1 голос
/ 07 ноября 2010

Фильтр действий кажется хорошей идеей:

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 голосов
/ 09 ноября 2010

Думаю, я что-то упустил.Это то, чего я пытаюсь избежать (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, чтобы извлечь текущую культуру из сеанса:1006 *

    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, либо создать базовый контроллер.

0 голосов
/ 09 ноября 2010

Существует гораздо лучшее и масштабируемое (с точки зрения гибкости) решение этой проблемы, которое было решено при использовании 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 в одной папке представлений, означает, что обо всем позаботятся за вас.

Надеюсь, что поможет!
Всего наилучшего,
Роб

...