Как исключить поле из @Html.EditForModel(), но показать его с помощью Html.DisplayForModel()

Я читаю на ASP.NET MVC и все это забавное использование, и я только что узнал о DataTemplates.

Спеша проверить это, я перевел одну из своих более простых моделей на использование @Html.DisplayForModel() а также @Html.EditForModel() и это сработало как талисман:)

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

3 ответа

Решение

Вы можете использовать интерфейс IMetadataAware в качестве атрибута create, который будет устанавливать ShowForEdit и ShowForDislay в метаданных:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class TemplatesVisibilityAttribute : Attribute, IMetadataAware
{
    public bool ShowForDisplay { get; set; }

    public bool ShowForEdit { get; set; }

    public TemplatesVisibilityAttribut()
    {
        this.ShowForDisplay = true;
        this.ShowForEdit = true;
    }

    public void OnMetadataCreated(ModelMetadata metadata)
    {
        if (metadata == null)
        {
            throw new ArgumentNullException("metadata");
        }

        metadata.ShowForDisplay = this.ShowForDisplay;
        metadata.ShowForEdit = this.ShowForEdit;
    }

}

Затем вы можете прикрепить его к вашей собственности следующим образом:

public class TemplateViewModel
{
  [TemplatesVisibility(ShowForEdit = false)]
  public string ShowForDisplayProperty { get; set; }

  public string ShowAlwaysProperty { get; set; }
}

И это все, что вам нужно.

Вы можете написать собственный поставщик метаданных и установить ShowForEdit свойство метаданных. Итак, начнем с пользовательского атрибута:

public class ShowForEditAttribute : Attribute
{
    public ShowForEditAttribute(bool show)
    {
        Show = show;
    }

    public bool Show { get; private set; }
}

затем поставщик метаданных пользовательской модели:

public class MyModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(
        IEnumerable<Attribute> attributes,
        Type containerType, 
        Func<object> modelAccessor, 
        Type modelType, 
        string propertyName
    )
    {
        var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
        var sfea = attributes.OfType<ShowForEditAttribute>().FirstOrDefault();
        if (sfea != null)
        {
            metadata.ShowForEdit = sfea.Show;
        }
        return metadata;
    }
}

затем зарегистрируйте этого провайдера в Application_Start:

ModelMetadataProviders.Current = new MyModelMetadataProvider();

и, наконец, украсить:

public class MyViewModel
{
    [ShowForEdit(false)]
    public string Prop1 { get; set; }

    public string Prop2 { get; set; }
}

Теперь, если на ваш взгляд у вас есть:

@model MyViewModel

<h2>Editor</h2>
@Html.EditorForModel()

<h2>Display</h2>
@Html.DisplayForModel()

Prop1 свойство не будет включено в шаблон редактора.

Примечание: вы можете сделать то же самое с ShowForDisplay свойство метаданных.

Можете ли вы отобразить каждое из полей, которые вы хотите, используя Html.DisplayTextbox или один из других вариантов? Таким образом, вы также можете настроить внешний вид и метки, относящиеся к полю.

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