Локализация ASP.NET MVC 3 с DisplayAttribute и пользовательским поставщиком ресурсов - PullRequest
14 голосов
/ 02 февраля 2011

Я использую пользовательский поставщик ресурсов для получения строк ресурсов из базы данных. Это прекрасно работает с ASP.NET, где я могу определить тип ресурса в виде строки. Атрибуты метаданных для свойств модели в MVC 3 (например, [Range], [Display], [Required] требуют тип ресурса в качестве параметра, где ResourceType - это тип сгенерированного класса code-behind файла .resx .

    [Display(Name = "Phone", ResourceType = typeof(MyResources))]
    public string Phone { get; set; }

Поскольку у меня нет файлов .resx, такого класса не существует. Как я могу использовать атрибуты модели с пользовательским поставщиком ресурсов?

Я бы хотел что-то вроде этого:

    [Display(Name = "Telefon", ResourceTypeName = "MyResources")]
    public string Phone { get; set; }

Для этого DisplayNameAttribute из System.ComponentModel имеет перезаписываемое свойство DisplayName, но класс DisplayAttribute запечатан. Для атрибутов проверки соответствующие классы не существуют.

Ответы [ 3 ]

7 голосов
/ 08 февраля 2012

Самый чистый способ, который я придумал, это переопределить DataAnnotationsModelMetadataProvider. Вот очень аккуратная статья о том, как это сделать.

http://buildstarted.com/2010/09/14/creating-your-own-modelmetadataprovider-to-handle-custom-attributes/

4 голосов
/ 10 апреля 2013

Вы можете расширить DisplayNameAttribute и переопределить строковое свойство DisplayName.У меня есть что-то вроде этого

    public class LocalizedDisplayName : DisplayNameAttribute
    {
        private string DisplayNameKey { get; set; }   
        private string ResourceSetName { get; set; }   

        public LocalizedDisplayName(string displayNameKey)
            : base(displayNameKey)
        {
            this.DisplayNameKey = displayNameKey;
        }


        public LocalizedDisplayName(string displayNameKey, string resourceSetName)
            : base(displayNameKey)
        {
            this.DisplayNameKey = displayNameKey;
            this.ResourceSetName = resourceSetName;
        }

        public override string DisplayName
        {
            get
            {
                if (string.IsNullOrEmpty(this.GlobalResourceSetName))
                {
                    return MyHelper.GetLocalLocalizedString(this.DisplayNameKey);
                }
                else
                {
                    return MyHelper.GetGlobalLocalizedString(this.DisplayNameKey, this.ResourceSetName);
                }
            }
        }
    }
}

Для MyHelper методы могут быть примерно такими:

public string GetLocalLocalizedString(string key){
    return _resourceSet.GetString(key);
}

Очевидно, вам нужно будет добавить обработку ошибок и иметь resourceReaderнастроить.Подробнее здесь

С этим вы затем украсите свою модель новым атрибутом, передавая ключ ресурса, из которого вы хотите получить значение, например

[LocalizedDisplayName("Title")]

Тогда Html.LabelFor автоматически отобразит локализованный текст.

2 голосов
/ 26 февраля 2011

Я думаю, вам придется переопределить свойства DataAnnotations, чтобы локализовать их с поставщиком ресурсов БД. Вы можете наследовать от текущих, а затем указать дополнительные свойства, такие как строка подключения к БД, которые будут использоваться при получении ресурсов от вашего пользовательского провайдера.

...