是否可以创建条件属性作为DisplayIf?
我想创建一个与我的viewmodel一起使用的属性。 我想根据第三个值显示不同的文本字符串。
我想做这样的事……
[DisplayIf("IsPropertyValid", true, Name="value 1")] [DisplayIf("IsPropertyValid", false, Name="value 2")] public string MyProperty { get; set; } public bool IsPropertyValid { get; set; }
根据我的值IsPropertyValid是否为真,我想显示一个或另一个。 IE浏览器。 当属性IspPropertyValid等于true时,“value 1”将是displaytext,如果不是,则它将是“value 2”。
这是否可以使用ASPNET.MVC属性? 或者甚至更好……像……一样的组合……
[DisplayIf("IsPropertyValid", new {"value 1", "value 2"})]. public string MyProperty { get; set; } public bool IsPropertyValid { get; set; }
然后该属性检查IsPropertyValid的值,并确保显示的值为“value 1”或“value 2”。
这是一个如何解决这个问题的例子。
我们要做的是创建一个名为Person的简单类,并显示一些关于它们的基本信息。
一个人有两个属性
- 名称
- 活跃
IsActive
属性是bool值,将是用于确定用户名称显示内容的属性。
最终我们要做的是将名为DisplayIf
的新属性应用于Name属性。 它看起来像这样:
[DisplayIf("IsActive", "This value is true.", "This value is false.")]
首先,让我们创建我们的模型。 创建一个名为Person的类,并将其放入Models文件夹中。
型号/ Person.cs
public class Person { [DisplayIf("IsActive", "This value is true.", "This value is false.")] public string Name { get; set; } public bool IsActive { get; set; } }
创建一个名为Attributes的文件夹,然后将以下类放入其中:
属性/ 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; } }
让我们创建一个简单的控制器和动作。 我们将使用common / Home / Index 。
控制器/ 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); } }
创建一个名为ViewModels的新文件夹并创建一个HomeViewModels.cs类。
的ViewModels / HomeViewModels.cs
public class HomeIndexViewModel { public IEnumerable Persons { get; set; } }
我们的索引视图非常简单。
查看/主页/ Index.cshtml
@model HomeIndexViewModel @{ ViewBag.Title = "Index"; } Index
@Html.DisplayForModel()
创建此显示模板时, DisplayForModel
将起作用:
查看/主页/ 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()) { @Html.DisplayIfFor(x => prop)
} else { @Html.DisplayFor(x => prop.Model)
} }
但是这个显示模板中的这些方法是什么? 创建一个名为Extensions的新文件夹并添加以下类:
扩展/ 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; } }
扩展/ HtmlHelperExtensions.cs
public static class HtmlHelperExtensions { public static IHtmlString DisplayIfFor (this HtmlHelper helper, Expression> 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); } }
最终输出: