Итак, это то, что я сделал.
Мне пришлось сделать этот код более локальным для моего конкретного проекта, потому что он опирается на класс ресурса, передаваемый в виде открытого статического свойства ResourceManager
типа System.Resources.ResourceManager
.Это верно для класса, сгенерированного собственными строго типизированными классами доступа к ресурсам VS (сгенерированными из файлов .resx), и поэтому я думаю, что он, вероятно, квалифицируется как повторно используемый.Он использует это, так что он может указать культуру, которая будет использоваться при поиске строк.
Сначала выполняется поиск ресурса (с использованием CurrentCulture
) для имени ресурса, которое будет использоваться для свойства модели.текст;затем он перекачивает эту строку обратно в другой поиск ресурсов (используя CurrentUICulture
), чтобы получить фактическое отображаемое имя, которое будет использоваться.
Я заменил всю проверку ошибок на TODO, чтобы сохранить ее краткой.
В конце концов, я получил непосредственно из DisplayNameAttribute
, потому что этот новый шаблон не очень хорошо сочетался с кодом, который я использовал (оторванный от RequiredAttribute
), чтобы получить строки ресурсов на основе UICulture для моего собственного существующего настраиваемого атрибута.Мне не нравится имя класса, но я не могу придумать ничего лучшего прямо сейчас.
public class CultureDrivenDisplayNameAttribute : DisplayNameAttribute
{
private readonly string _displayName = null;
public CultureDrivenDisplayNameAttribute(Type resourceType,
string resourceNameLookup)
{
//TODO: check for null args
//get the ResourceManager member
var prop = resourceType.GetProperty(
"ResourceManager",
System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.Static);
//TODO: check for null or unexpected property type.
System.Resources.ResourceManager resourceManager =
prop.GetValue(null, null) as System.Resources.ResourceManager;
//TODO: check for null
//ResourceManager is used as it lets us specify the culture - we need this
//to be able to lookup first on Culture, then by UICulture.
string finalResourceName =
resourceManager.GetString(resourceNameLookup,
Thread.CurrentThread.CurrentCulture);
//TODO: check for null/whitespace resource value
_displayName = resourceManager.GetString(finalResourceName,
Thread.CurrentThread.CurrentUICulture);
//TODO: check for null display name
}
public override string DisplayName
{
get
{
return _displayName;
}
}
}
Итак, теперь я украшаю свойства PostZip / CountyState моей адресной модели следующим образом:
[CultureDrivenDisplayName(typeof(StringResources),
"ResourceName_AddressDetails_CountyState")]
public string CountyState { get; set; }
[CultureDrivenDisplayName(typeof(StringResources),
"ResourceName_AddressDetails_PostZip")]
public string PostZip { get; set; }
И затем, в моем нейтральном файле ресурсов:
ResourceName_AddressDetails_CountyState: "DisplayName_AddressDetails_CountyState"
ResourceName_AddressDetails_PostZip: "DisplayName_AddressDetails_PostZip"
DisplayName_AddressDetails_CountyState: "County/State"
DisplayName_AddressDetails_PostZip: "Post/Zip Code"
Так что, если я не настроил файлы ресурсов для данной культуры, адрес отобразит разумный текст.
Но в моем файле ресурсов en-GB:
ResourceName_AddressDetails_CountyState: "DisplayName_AddressDetails_CountyState_GB"
ResourceName_AddressDetails_PostZip: "DisplayName_AddressDetails_PostZip_GB"
DisplayName_AddressDetails_CountyState_GB: "County"
DisplayName_AddressDetails_PostZip_GB: "Post Code"
Так что теперь, независимо от культуры пользовательского интерфейса, на английском сайте всегда будет отображаться 'County' или 'Post Code';но культура пользовательского интерфейса может обеспечить собственный локальный перевод обеих фраз, если пожелает, просто определяя локализованные версии _GB
суффиксированных строк ресурсов.
Я также понял, что мне может потребоваться выполнитьто же самое для целых страниц, поэтому я собираюсь расширить движки представлений Razor и Aspx для автоматической поддержки версий на основе культуры и пользовательского интерфейса, использующих подпапки.единственная проблема заключается в том, как интерпретировать папку /en-GB/
- это относится к фоновой или внешней культуре!