以下是如何进行此操作的示例。
我们要做的是创建一个简单的类,名为Person并显示有关它们的一些基本信息。
一个人有两个属性
The IsActive
property 是一个 bool 值,将用于确定用户名的显示形式。
最终我们要做的是应用一个名为DisplayIf
到名称属性。它看起来像这样:
[DisplayIf("IsActive", "This value is true.", "This value is false.")]
首先,让我们创建我们的模型。创建一个名为Person并将其放入Models folder.
模型/人物.cs
public class Person
{
[DisplayIf("IsActive", "This value is true.", "This value is false.")]
public string Name { get; set; }
public bool IsActive { get; set; }
}
创建一个名为的文件夹属性然后将以下类放入其中:
属性/DisplayIfAttribute.cs
public class DisplayIfAttribute : Attribute
{
private string _propertyName;
private string _trueValue;
private string _falseValue;
public string PropertyName
{
get { return _propertyName; }
}
public string TrueValue
{
get { return _trueValue; }
}
public string FalseValue
{
get { return _falseValue; }
}
public DisplayIfAttribute(string propertyName, string trueValue, string falseValue)
{
_propertyName = propertyName;
_trueValue = trueValue;
_falseValue = falseValue;
}
}
让我们创建一个简单的控制器和操作。我们将使用通用的/首页/索引.
控制器/HomeController.cs
public class HomeController : Controller
{
public ActionResult Index()
{
HomeIndexViewModel viewModel = new HomeIndexViewModel();
Person male = new Person() { Name = "Bob Smith", IsActive = true };
Person female = new Person() { Name = "Generic Jane", IsActive = false };
Person[] persons = {male, female};
viewModel.Persons = persons;
return View(viewModel);
}
}
创建一个名为的新文件夹视图模型并创建一个HomeViewModels.cs class.
ViewModels/HomeViewModels.cs
public class HomeIndexViewModel
{
public IEnumerable<Person> Persons { get; set; }
}
Our Index视图很简单。
视图/Home/Index.cshtml
@model HomeIndexViewModel
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div>
@Html.DisplayForModel()
</div>
DisplayForModel
当您创建此显示模板时将起作用:
视图/Home/DisplayTemplates/HomeIndexViewModel.cshtml
@model HomeIndexViewModel
@Html.DisplayFor(m => m.Persons)
DisplayFor
-> 当您创建此显示模板时,人员将起作用:
视图/共享/DisplayTemplates/Person.cshtml
@model Person
@foreach (var prop in ViewData.ModelMetadata.Properties)
{
if (prop.HasDisplayIfAttribute())
{
<p>@Html.DisplayIfFor(x => prop)</p>
}
else
{
<p>@Html.DisplayFor(x => prop.Model)</p>
}
}
但是这个显示模板中的这些方法是什么?创建一个名为的新文件夹扩展并添加以下类:
扩展/ModelMetaDataExtensions.cs
public static class ModelMetaDataExtensions
{
public static bool HasDisplayIfAttribute(this ModelMetadata data)
{
var containerType = data.ContainerType;
var containerProperties = containerType.GetProperties();
var thisProperty = containerProperties.SingleOrDefault(x => x.Name == data.PropertyName);
var propertyAttributes = thisProperty.GetCustomAttributes(false);
var displayIfAttribute = propertyAttributes.FirstOrDefault(x => x is DisplayIfAttribute);
return displayIfAttribute != null;
}
}
扩展/HtmlHelper Extensions.cs
public static class HtmlHelperExtensions
{
public static IHtmlString DisplayIfFor<TModel, TProperty>
(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
where TProperty : ModelMetadata
{
string returnValue = string.Empty;
var modelMetaData = expression.Compile().Invoke(helper.ViewData.Model);
var containerType = typeof(TModel);
var containerProperties = containerType.GetProperties();
var propertyInfo = containerProperties
.SingleOrDefault(x => x.Name == modelMetaData.PropertyName);
var attribute = propertyInfo.GetCustomAttributes(false)
.SingleOrDefault(x => x is DisplayIfAttribute) as DisplayIfAttribute;
var conditionalTarget = attribute.PropertyName;
var conditionalTargetValue = (bool)containerType
.GetProperty(conditionalTarget).GetValue(helper.ViewData.Model);
if (conditionalTargetValue)
{
returnValue = attribute.TrueValue;
}
else
{
returnValue = attribute.FalseValue;
}
return MvcHtmlString.Create(returnValue);
}
}
最终输出: