Вопрос:

Переопределить аннотацию отображаемого имени модели MVC с помощью пользовательских функций

c# asp.net-mvc asp.net-mvc-4 data-annotations modelstate

46 просмотра

3 ответа

1530 Репутация автора

У меня есть следующий метод, где я читаю из XML-файла значения ключа. Я передаю ключ и мне возвращается значение, которое я использовал для отображения в моем представлении.

public static class TextManager
{
    public static string GetValue(string key)
    {
        string returnVal = null; 
        XmlSerializer serializer = new XmlSerializer(typeof(Entries));
        string path = HttpContext.Current.Server.MapPath("/App_Data/text-key-value.xml");
        if (File.Exists(path))
        {
            Entries entries = (Entries)serializer.Deserialize(File.OpenRead(path));
            var entry = entries.Where(u => u.Key == key).FirstOrDefault();
            if (entry != null)
            {
                returnVal = entry.Value;
            }
        }
        return returnVal;
    }
}

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

Например, я хочу заменить

[Display(Name = "Reference Code")]
public string ReferenceCode { get; set; }

С этим

[DisplaySiteText("ReferenceCodeKey")]
public string ReferenceCode { get; set; }

DisplaySiteText передаст строковую ссылку "ReferenceCodeKey" методу GetValue, сохранит ссылку в файле и затем установит для стандартного атрибута отображаемого имени то, что было в файле.

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

Автор: TroySteven Источник Размещён: 08.08.2019 03:38

Ответы (3)


0 плюса

11494 Репутация автора

Возможно, ваш DisplaySiteTextатрибут мог бы наследовать от Displayатрибута и установить имя с помощью вашего вспомогательного класса. Что-то вроде этого:

public class DisplaySiteTextAttribute : DisplayAttribute
{
    public DisplaySiteTextAttribute(string key)
    {
        Name = TextManager.GetValue(key);
    }
}
Автор: Mun Размещён: 08.08.2019 03:46

1 плюс

3682 Репутация автора

Вы можете наследовать DisplayNameAttributeдля этой цели

public class DisplaySiteTextAttribute : DisplayNameAttribute
{
    private string _key;

    public ResourceDisplayAttribute(string key)
    {
        _key = key;
    }

    public override string DisplayName
    {
        get
        {
            return TextManager.GetValue(_key);
        }
    }
}
Автор: Alexander Размещён: 10.08.2019 08:08

0 плюса

73411 Репутация автора

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

На самом деле это ответственность за ModelMetaDataProviderполучение метаданных для модели, включая отображаемый текст для свойств. Таким образом, в качестве опции, без изменения Displayатрибута, вы можете создать новый поставщик метаданных модели и вернуть метаданные свойства из другого источника. Для этого:

  1. Создайте нового поставщика метаданных, производного от DataAnnotationsModelMetadataProvider.
  2. Переопределить GetMetadataForPropertyи вызвать базу, чтобы получить метаданные. Затем измените DisplayNameна основе вашей логики (читая из вашего текстового менеджера.)
  3. Зарегистрируйте нового поставщика метаданных как ModelMetadataProviders.Currentв App_Start.

Код

using System;
using System.Web.Mvc;
public class MyCustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName)
    {
        var metadata = base.GetMetadataForProperty(modelAccessor, containerType, propertyName);
        metadata.DisplayName = "Something else";
        return metadata;
    }
} 
Автор: Reza Aghaei Размещён: 11.08.2019 07:50
Вопросы из категории :
32x32