【问题标题】:Change Display Name conditionally in View Model在视图模型中有条件地更改显示名称
【发布时间】:2018-10-12 08:27:51
【问题描述】:

我是 Razor 和 View Models 的新手,我只是想问一下是否可以在 [Display(Name = "")] 中显示不同的字符串

我尝试在显示和变量之间添加条件,但它显示错误

也试过了

public string Color {get;set;}
public String ColorDisplay
        {
            get
            {
                String name = "";
                if (ColorId == 25 || ColorId == 26)
                {
                    name = "Purple";
                }
                else
                {
                    name = "Green";
                }

                return name;
            }
        }

然后在我看来 @Html.LabelFor(m => m.ColorDisplay)

但似乎不起作用,因为它只是显示ColorDisplay

【问题讨论】:

  • ColorId 是一个 int 属性吗?听起来您可以创建自定义属性,例如[DisplayWhen("ColorId", 25, 26, "Purple", "Green")]
  • @TetsuyaYamamoto 是 colorid 25 还是 26 仍然像您提供的那样工作?是的,colorId 在int
  • 请注意,这是我提出的自定义属性,默认的DisplayAttribute 没有这样的参数。我首先想知道的是ColorId 定义为模型类或局部变量/字段的一部分的属性。
  • @TetsuyaYamamoto 是的,它包含在我当前的视图模型中,为 int ColorId

标签: c# html razor model viewmodel


【解决方案1】:

在这个问题中,您可能需要一个自定义属性来根据属性属性中提供的值更改文本。假设您想要这样的自定义属性用法:

[DisplayWhen("ColorId", 25, 26, "Purple", "Green")]
public String Color { get; set; }

并像这样使用 HTML 助手:

@Html.LabelFor(m => m.Color)

那么你应该做这些步骤:

1) 创建一个继承自Attribute 类的自定义属性。

public class DisplayWhenAttribute : Attribute
{
    private string _propertyName;
    private int _condition1;
    private int _condition2;
    private string _trueValue;
    private string _falseValue;

    public string PropertyName 
    {
       get
       {
           return _propertyName;
       }
    }

    public int Condition1
    {
       get
       {
           return _condition1;
       }
    }

    public int Condition2
    {
       get
       {
           return _condition2;
       }
    }

    public string TrueValue
    {
       get
       {
           return _trueValue;
       }
    }

    public string FalseValue
    {
       get
       {
           return _falseValue;
       }
    }

    public DisplayWhenAttribute(string propertyName, int condition1, int condition2, string trueValue, string falseValue)
    {
        _propertyName = propertyName;
        _condition1 = condition1;
        _condition2 = condition2;
        _trueValue = trueValue;
        _falseValue = falseValue;
    }
}

2) 创建自定义元数据提供程序类,检查自定义属性是否存在。

public class CustomModelMetadataProvider : 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 additionalAttribute = attributes.OfType<DisplayWhenAttribute>().FirstOrDefault();

        if (additionalAttribute != null)
        {
            metadata.AdditionalValues.Add("DisplayWhenAttribute", additionalValues);
        }

        return metadata;
    }
}

3) 将CustomModelMetadataProvider 注册到 Global.asax 中的Application_Start() 方法中,如下所示:

protected void Application_Start()
{
    ModelMetadataProviders.Current = new CustomModelMetadataProvider();
}

4) 创建您自己的(或覆盖现有的)LabelFor 助手,以便它检查 DisplayWhenAttribute,如下例所示:

public static MvcHtmlString LabelFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
{
    string result = string.Empty;

    var modelMetaData = expression.Compile().Invoke(helper.ViewData.Model);
    string fieldName = ExpressionHelper.GetExpressionText(expression);

    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 DisplayWhenAttribute) as DisplayWhenAttribute;

    var target = attribute.PropertyName; // target property name, e.g. ColorId
    var condition1 = attribute.Condition1; // first value to check
    var condition2 = attribute.Condition2; // second value to check

    var targetValue = (int)containerType.GetProperty(target).GetValue(helper.ViewData.Model);  

    // checking provided values from attribute
    if (targetValue == condition1 || targetValue == condition2)
    {
        result = attribute.TrueValue;
    }      
    else
    {
        result = attribute.FalseValue;
    }

    // create <label> tag with specified true/false value
    TagBuilder tag = new TagBuilder("label");
    tag.MergeAttributes(htmlAttributes);
    tag.Attributes.Add("for", helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(fieldName));
    tag.SetInnerText(result);

    return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
}

需要考虑的一些参考:

Is it possible to create conditional attribute as DisplayIf?

How to extend MVC3 Label and LabelFor HTML helpers?

MVC custom display attribute

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    相关资源
    最近更新 更多