Как исключить поле из @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 или один из других вариантов? Таким образом, вы также можете настроить внешний вид и метки, относящиеся к полю.