2010-11-07 2 views
4

Я использую spark viewengine, asp.net mvc и .resx файлы.Spark Глобализация с ASP.NET MVC

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

+0

что образец, о котором он говорит, является именно тем, что имеет проблему, он сохраняет информацию на простом сеансе ASP.NET и должен запрашивать ее на каждом дополнительном контроллере. – Andrew

ответ

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

+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. –

+0

Я закончил использование: http://weblogs.asp.net/psteele/archive/2009/11/04/using-windsor-to-inject-dependencies-into-asp-net-mvc-actionfilters.aspx, вводя мой сеанс в пользовательский ActionFilterAttribute, и он сработал. Спасибо за вашу помощь. – Andrew

0

Существует гораздо лучшее и масштабируемое (с точки зрения гибкости) решение этой проблемы, которое было решено, если вы используете Spark View Engine.

Посмотрите на sample solution here in the code base за отличный пример того, как сделать интернационализацию или глобализацию с помощью Spark. Нет абсолютно никакой необходимости начинать делать фантастические вещи с помощью ActionFilters - и этот метод работает в MVC2 и MVC3, чтобы обеспечить легкую миграцию, если это ваш будущий план.

Update

В ответ на ваш другой вопрос относительно образца в кодовой базе искрового я думаю, есть несколько способов снятия шкуры этого кота. Одним из способов было бы сохранить культуру как часть сессии, но в прошлых проектах, где мы этого не хотели, мы сделали то, что уже сделали многие веб-сайты - мы включили культуру в качестве параметра в данные маршрута, убедившись, что это включен в URL:

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

Такого рода вещи в сочетании с модулем Спарка я уже упоминал выше, даю вам свободу, чтобы просто провести время с акцентом на ваши .resx файлов вместо всех своего времени выяснить культуру и маршрутизации вручную.

Тот факт, что у вас есть Index.spark и Index.fr.spark в одной и той же папке видов, означает, что остальное позаботится о вас.

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

+0

см. Ответ ниже, был для того, чтобы вписаться в эту маленькую коробку. – Andrew

+0

Я добавил обновление к своему ответу. Надеюсь, я накрыл его? – RobertTheGrey

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

Смежные вопросы