ASP.NET MVC: почему я не могу установить метаданные модели ShowForEdit с атрибутом?

Почему я не могу установить ShowForEdit модель метаданных с атрибутом?

Кажется, что единственный атрибут, предоставленный, чтобы изменить это [ScaffoldColumn], который устанавливает оба ShowForEdit а также ShowForDisplayЭто не то, что я хочу сделать. Я хочу иметь возможность комментировать два отдельно от моей модели.

2 ответа

Решение

Потому что это не поддерживается из коробки. AFAIK причина в том, что атрибут dataannotations, поддерживающий эту функциональность, находится в.net 4.0, и для обеспечения совместимости MVC 3.5 и 4.0 их пришлось исключить.

Самый простой способ исправить это - реализовать собственный атрибут Edit/Show, как показано в этом вопросе / ответе:

Отображение различных полей в режиме EditorForModel и DisplayForModel в MVC2

К какому типу недвижимости вы применяете его? Если мы используем Reflector, мы можем обнаружить, что свойства ShowForEdit и ShowForDisplay используются в следующих функциях:

ShowForEdit: System.Web.Mvc.Html.DefaultEditorTemplates.ShouldShow (...)

ShowForDisplay: System.Web.Mvc.Html.DefaultDisplayTemplates.ShouldShow (...)

Определение этих методов:

private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo)
{
  return (((metadata.ShowForEdit && (metadata.ModelType != typeof(EntityState))) && !metadata.IsComplexType) && !templateInfo.Visited(metadata));
}

private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo)
{
  return (((metadata.ShowForDisplay && (metadata.ModelType != typeof(EntityState))) && !metadata.IsComplexType) && !templateInfo.Visited(metadata));
}

Игнорируя очевидную проверку свойства (metadata.ShowForX), вы можете видеть, что она проверяет, является ли модель экземпляром EntityState (вероятно, нет), а затем проверяет metadata.IsComplexType.

Мы можем посмотреть на свойство IsComplexType здесь:

public virtual bool IsComplexType
{
  get
  {
    return !TypeDescriptor.GetConverter(this.ModelType).CanConvertFrom(typeof(string));
  }
}

Это говорит о том, что он вернет true, если модель не может быть преобразована из строки, а в методах ShouldShow() он покажет, что это не сложный тип, т. Е. Значение МОЖЕТ быть преобразовано из строки.

Что вам нужно будет сделать, это создать TypeConverter, который может преобразовать строку в модель, например:

Модель:

[TypeConverter(typeof(ItemConverter))]
public class Item 
{
  #region Properties
  public string Text { get; set; }
  #endregion
}

И конвертер:

public class ItemConverter : TypeConverter
{
  #region Methods
  public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
  {
    if (sourceType == typeof(string))
      return true;

    return base.CanConvertFrom(context, sourceType);
  }

  public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
  {
    if (value.GetType() == typeof(string)) 
    {
      return new Item { Text = (string)value };
    }

    return base.ConvertFrom(context, culture, value);
  }
  #endregion
}

С этим на месте, попробуйте еще раз и посмотрите, поможет ли это.

Другие вопросы по тегам