Как загрузить различные файлы RESX на основе некоторого параметра

У меня есть ASP.NET страница ASP.NET3.5 (С#), которая интернационализирована на 10 разных языках.

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

EDIT: Я использую синтаксис meta:resourcekey в каждом asp-элементе управления, который позволяет использовать декларативный синтаксис для выражений Implicit Resource.

Меня попросили "маркировать" страницу на основе некоторого параметра строки запроса. Брендинг будет означать не просто загрузку разных файлов CSS, но также наличие разных текстовых сообщений (на всех языках).

Есть ли простой способ "свопинга" файлов resx без необходимости вручную получать ресурсы для каждого из сотен литералов и изображений, которые у меня есть на этой странице?

Другими словами, скажем, у меня есть следующие файлы RESX:

brand1_myPage.aspx.en-US.resx
brand1_myPage.aspx.de-DE.resx
brand1_myPage.aspx.fr-FR.resx

brand2_myPage.aspx.en-US.resx
brand2_myPage.aspx.de-DE.resx
brand2_myPage.aspx.fr-FR.resx

myPage.aspx будет искать файлы resx с именем myPage.xx-XX.resx.

Есть ли способ загрузить вместо этого файлы brand1xxx.resx или brand2xxx.resx на основе какого-то значения?

Спасибо заранее.

Ответы

Ответ 1

Вы можете использовать пользовательские культуры для достижения этого эффекта.

Сначала создайте и зарегистрируйте пользовательские культуры в системе, например:

CultureAndRegionInfoBuilder builder = new CultureAndRegionInfoBuilder("en-US-brand1", CultureAndRegionModifiers.None);
CultureInfo parentCI = new CultureInfo("en-US");
RegionInfo parentRI = new RegionInfo("en-US");
builder.LoadDataFromCultureInfo(parentCI);
builder.LoadDataFromRegionInfo(parentRI);
builder.Parent = parentCI;
// set other properties of the custom culture (CultureEnglishName, CultureNativeName, possibly other ones)
// ...
builder.Register();

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

После того, как вы установили культуры, создайте файлы resx, как обычно, но используйте пользовательские имена культур (myPage.aspx.en-US-brand1.resx и т.д.).

Теперь все, что осталось сделать, это установить System.Threading.Thread.CurrentThread.CurrentUICulture на основе некоторого параметра (чем раньше, тем лучше, BeginRequest - это хорошее место или Page_PreInit, если вы хотите это только для некоторых страниц):

CultureInfo ci = new CultureInfo(Request.QueryString["paramname"]);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;

(установка CurrentCulture на самом деле не требуется, поскольку ресурсы работают с точки зрения CurrentUICulture, но установка обоих позволяет вам дополнительно настраивать страницу для каждой марки, например, использовать разные настройки формата даты и времени для каждой пользовательской культуры/бренда)

Некоторые примечания:

  • это решение дает вам большую гибкость, так как нормальный возврат к культуре действует - если запись не найдена для en-US-brandX, время выполнения вернется в en-US и так далее; это может значительно уменьшить дубликаты записей resx, если бренды в основном похожи, поскольку вы можете поместить некоторые записи только в родительский (en-US) resx файл,
  • вы можете создать больше уровней унаследованных культур, например en-US-brandX-variantY,
  • все методы доступа к ресурсам работают как ожидалось,
  • изменение культуры рабочего потока означает, что вы получите локализованные сообщения об исключениях, если вы настроите культуру, скажем, de-DE-brandX, и у вас установлена ​​локализация de-DE, установленная в ОС,
  • по вышеуказанной причине вы можете захотеть reset текущей культуры (UI) в CultureInfo.InvariantCulture в Application_Error или даже лучше, как только вы поймаете исключение, которое, как вы знаете, приведет к Application_Error; это предотвратит локализацию стандартной желтой страницы смерти и, по крайней мере, части стека исключений,
  • вы можете подумать о создании сервисного инструмента, который будет регистрировать/отменять регистрацию/обновлять культуры, особенно если вы ожидаете частых изменений,
  • Это решение может быть проблематичным, если вы используете обнаружение культуры на основе клиента.

Ответ 2

Если вы ссылаетесь на ресурсы в своем коде следующим образом: Resources.brand1_myPage.WelcomeMessage, то это может быть сложно.

Но вы также можете программно извлекать ресурсы: GetGlobalResourceObject ("brand1_myPage", "WelcomeMessage"). Здесь у вас есть место для манипуляции с именем файла ресурса.