是否可以将条件属性创建为DisplayIf? [英] Is it possible to create conditional attribute as DisplayIf?

查看:76
本文介绍了是否可以将条件属性创建为DisplayIf?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个与视图模型一起使用的属性.我想根据第三个值显示不同的文本字符串.

I want to create an attribute to use with my viewmodel. I want to display different textstrings depending on a third value.

我想做这样的事情...

I would like to do something like this...

[DisplayIf("IsPropertyValid", true, Name="value 1")]
[DisplayIf("IsPropertyValid", false, Name="value 2")]
public string MyProperty { get; set; }

public bool IsPropertyValid { get; set; }

根据我的值IsPropertyValid是否为true,我要显示一个或另一个. IE.当属性IspPropertyValid等于true时,"value 1"将是显示文本,否则,将是"value 2".

Depending on whether my value IsPropertyValid is true or not I want to show one or the other. Ie. When property IspPropertyValid equals true "value 1" will be the displaytext and if not it will be "value 2".

使用ASPNET.MVC属性可能吗?甚至更好...像这样的组合....

Is this possible with ASPNET.MVC attributes? Or even better... a combinated one like....

[DisplayIf("IsPropertyValid", new {"value 1", "value 2"})].
public string MyProperty { get; set; }

public bool IsPropertyValid { get; set; }

然后,该属性检查IsPropertyValid的值,并确保显示的值为值1"或值2".

Then the attribute checks the value of IsPropertyValid and makes sure the value displayed is "value 1" or "value 2".

推荐答案

以下是如何解决此问题的示例.

Here's an example of how to go about this.

我们要做的是创建一个名为 Person 的简单类,并显示有关它们的一些基本信息.

What we'll do is create a simple class called Person and display some basic information about them.

一个人有两个属性

  • 名称
  • IsActive

IsActive属性是一个布尔值,它将是用于确定用户名显示为什么的属性.

The IsActive property is a bool value and will be the property used to determine what the user's name is displayed as.

最终,我们要做的是将一个名为DisplayIf的新属性应用于Name属性.看起来像这样:

Ultimately what we'll do is apply a new attribute called DisplayIf to the Name property. It looks like this:

[DisplayIf("IsActive", "This value is true.", "This value is false.")]

首先,让我们创建模型.创建一个名为 Person 的类,并将其放入 Models 文件夹中.

First, let's create our model. Create a class called Person and put it into a Models folder.

public class Person
{
    [DisplayIf("IsActive", "This value is true.", "This value is false.")]
    public string Name { get; set; }
    public bool IsActive { get; set; }
}

创建一个名为 Attributes 的文件夹,然后将以下类放入其中:

Create a folder called Attributes and then put the following class in it:

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 .

Let's create a simple controller and action. We'll use the common /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 类.

Create a new folder called ViewModels and create a HomeViewModels.cs class.

public class HomeIndexViewModel
{
    public IEnumerable<Person> Persons { get; set; }
}

我们的索引视图非常简单.

@model HomeIndexViewModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<div>
    @Html.DisplayForModel()
</div>

DisplayForModel在创建此显示模板时将起作用:

DisplayForModel will work when you create this display template:

@model HomeIndexViewModel

@Html.DisplayFor(m => m.Persons)

DisplayFor->创建此显示模板时,人员将工作:

DisplayFor -> Persons will work when you create this display template:

@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>
    }
}

但是此显示模板中的这些方法是什么?创建一个名为扩展名的新文件夹,并添加以下类:

But what are these methods in this display template? Create a new folder called Extensions and add the following classes:

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;
    }
}

Extensions/HtmlHelperExtensions.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);
    }
}

最终输出:

这篇关于是否可以将条件属性创建为DisplayIf?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆