Не получаю .Resx на основе CurrentUICulture

1

У меня есть следующие два файла в моем проекте MVC:

Изображение 174551

Я устанавливаю культуру в свой global.asax следующим образом:

Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");

Я вижу в окне Immediate Window в Visual Studio значение Thread.CurrentThread.CurrentUICulture является "de-DE" во время визуализации представления.

Это подводит меня ко мне:

@Html.Raw(CurrentUICultureContent.ce_landingPage_welcomeText)

Проблема в том, что он выводит текст только из CurrentUICultureContent.resx, а не из текста CurrentUICultureContent.de.resx, даже если для CurrentUICulture установлено значение "de-DE".

Примечание. Я также попытался изменить имя файла на CurrentUiCultureContent.de-DE.resx, но это тоже не работает.

Изменить: я поставил точку останова на странице просмотра и проверил значение CurrentUICulture в окне Immediate; но он по-прежнему не получает текст из файла de-DE.resx:

System.Threading.Thread.CurrentThread.CurrentUICulture {de-DE}
    Calendar: {System.Globalization.GregorianCalendar}
    CompareInfo: {CompareInfo - de-DE}
    CultureTypes: SpecificCultures | InstalledWin32Cultures | FrameworkCultures
    DateTimeFormat: {System.Globalization.DateTimeFormatInfo}
    DisplayName: "German (Germany)"
    EnglishName: "German (Germany)"
    IetfLanguageTag: "de-DE"
    IsNeutralCulture: false
    IsReadOnly: false
    KeyboardLayoutId: 1031
    LCID: 1031
    Name: "de-DE"
    NativeName: "Deutsch (Deutschland)"
    NumberFormat: {System.Globalization.NumberFormatInfo}
    OptionalCalendars: {System.Globalization.Calendar[1]}
    Parent: {de}
    TextInfo: {TextInfo - de-DE}
    ThreeLetterISOLanguageName: "deu"
    ThreeLetterWindowsLanguageName: "DEU"
    TwoLetterISOLanguageName: "de"
    UseUserOverride: true

Почему он возвращает английский вместо ожидаемого файла ресурсов Германии?

Есть ли что-то дополнительное, что я должен сделать, чтобы заставить это работать?

Теги:
asp.net-mvc
localization
internationalization
resx

3 ответа

2
Лучший ответ

Извините за этот вопрос - проблема в том, что мы вручную загружали сборки (теневое копирование их), и существующая логика не помещала resource.DLL в правильную папку. .NET ожидает, что resource.DLL будет помещен в соответствующую папку культуры; то есть:

  • /Shadow_copy_folder
    • /ан
      • /resource.dll

Как только я обновил логику, чтобы создать папку теневой копии для культуры; .NET выбрал правильный файл ресурсов.

Кроме того, было что-то не так с тем, как я определял культуру. По-видимому, это должно быть сделано следующим образом:

Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("de-DE");
  • 0
    О, та же ошибка здесь
1

Переопределите execCore() контроллера и установите оба

Thread.CurrentThread.CurrentCulture and Thread.CurrentThread.CurrentUICulture

После сборки убедитесь, что у вас есть соответствующий файл ресурса в папке bin вашего проекта MVC, а также убедитесь, что у вас есть сценарий установщика для сбора этих файлов, чтобы у вас не было проблем в среде тестирования.

удачи...

1

Одним из способов применения многоязычной поддержки файлов ресурсов в MVC является отметка файла ресурсов как встроенного ресурса. Таким образом, вы можете использовать файл ресурсов как простой класс.

Чтобы пометить ваш файл ресурсов как Embedded Resource, вы можете сделать следующее, как показано на рисунке ниже:

  1. Измените модификатор доступа файла ресурса на Public.

Изображение 174551

  1. Затем измените следующие свойства файла ресурсов, как показано ниже. Вы можете свободно выбирать пространство имен для собственных инструментов по своему желанию:

Изображение 174551

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

Изображение 174551

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

EDIT: Как уже упоминалось ниже в моем комментарии, это глобальный фильтр действий. Сообщите мне, подходит ли это для вашей цели.

public class PersonalizeAttribute:ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string language = (string)(filterContext.RouteData.Values["language"] ?? "en");
        string culture = (string)(filterContext.RouteData.Values["culture"] ?? "US");

        CultureInfo ci = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture));

        Thread.CurrentThread.CurrentCulture = ci;
        Thread.CurrentThread.CurrentUICulture = ci;
    }
}

 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new PersonalizeAttribute());
    }

И да, я читаю информацию о культуре из URL (вы также можете использовать переменные сервера, чтобы уловить предпочтительную культуру пользователя).

routes.MapRoute(
            name: "",
            url: "{language}-{culture}/{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, language = "en", culture = "US" }
        );
  • 0
    Я собрал отдельный демонстрационный проект, и все работает отлично ... Не уверен, почему это не работает в моем существующем проекте. Возможно, это связано с тем, что мы делаем много зависимостей и теневое копирование сборок ... Все еще изучаем это. Спасибо за вашу помощь.
  • 1
    Хотя я не совсем уверен, но я думаю, что DI не должно влиять на текущую культуру. Однако в моем демонстрационном проекте я создал глобальный фильтр действий для установки текущей информации о культуре. Таким образом, гарантируется (в некоторой степени), что я устанавливаю культуру непосредственно перед тем, как мое действие будет выполнено в контроллере.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню