我想创建一个与我的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”。
答案 0 :(得分:4)
这是一个如何解决这个问题的例子。
我们要做的是创建一个名为 Person 的简单类,并显示一些关于它们的基本信息。
一个人有两个属性
IsActive
属性是bool值,将是用于确定用户名称显示为的属性。
最终我们要做的是将一个名为DisplayIf
的新属性应用于Name属性。它看起来像这样:
[DisplayIf("IsActive", "This value is true.", "This value is false.")]
首先,让我们创建我们的模型。创建一个名为 Person 的类,并将其放入 Models 文件夹中。
public class Person
{
[DisplayIf("IsActive", "This value is true.", "This value is false.")]
public string Name { get; set; }
public bool IsActive { get; set; }
}
创建一个名为属性的文件夹,然后将以下类放入其中:
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;
}
}
让我们创建一个简单的控制器和动作。我们将使用常见的 / Home / Index 。
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 类。
public class HomeIndexViewModel
{
public IEnumerable<Person> Persons { get; set; }
}
我们的索引视图非常简单。
@model HomeIndexViewModel
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div>
@Html.DisplayForModel()
</div>
创建此显示模板时, DisplayForModel
将起作用:
@model HomeIndexViewModel
@Html.DisplayFor(m => m.Persons)
DisplayFor
- &gt;创建此显示模板时,人员将工作:
@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>
}
}
但是这个显示模板中的这些方法是什么?创建一个名为 Extensions 的新文件夹,并添加以下类:
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;
}
}
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);
}
}
最终输出: