模型的Html助手或模型的任何可编辑字段的可见性开启和关闭

时间:2013-12-29 16:41:03

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 custom-attributes

我有一个模特说

public class Contact
{
    [Display(Name = "Phone Number", Description = "This is Phone number to contact")]
    [Visibility(ShowForDisplay=false)]
    public string Phone { get; set; }

    [Display(Name = "Mail To Support", Description = "This is Mail for support")]
    public string Email { get; set; }
}

现在在Mvc html中,我在

等几个地方做
@Html.DisplayTextFor(x=>x.Phone)

现在我想要一个基于这样的属性,可以在模型级别进行管理,以便将此显示转换为视图。例如,@html.DisplayTextFor(x=>x.Phone)应该在那里但是当我[Visibility(ShowForDisplay=false)]时,那么值或文本的所有可见性都不应该在html上呈现。

如何通过自定义属性[Visibility(ShowForDisplay=false)]之类的属性完成?

1 个答案:

答案 0 :(得分:0)

使用模型Html Helper的所有MetaData方法,您无法更改ModelMetada类,因此您应该创建自己的Html帮助程序,并且当然需要自定义属性。检查此代码:

首先创建一个自定义属性:

public class VisibilityAttribute : ValidationAttribute
{
    private bool _isVisible;

    public VisibilityAttribute(bool visible = true)
    {
        _isVisible = visible;
    }

    public bool ShowForDisplay
    {
        get
        {
            return _isVisible;
        }
        set
        {
            _isVisible = value;
        }
    }
}

然后创建一个Html帮助器:

public static class MyHtmlExtensions
{
    public static MvcHtmlString DisplayTextForCustom<TModel, TResult>(this HtmlHelper<TModel> html,
        Expression<Func<TModel, TResult>> expression)
    {
        ExpressionType type = expression.Body.NodeType;
        if (type == ExpressionType.MemberAccess)
        {
            MemberExpression memberExpression = (MemberExpression) expression.Body;
            PropertyInfo pi = memberExpression.Member as PropertyInfo;

            var attributes = pi.GetCustomAttributes(); 

            foreach (var attribute in attributes)
            {

                if (attribute is VisibilityAttribute)
                {
                    VisibilityAttribute vi = attribute as VisibilityAttribute;
                    if (vi.ShowForDisplay)  
                    {
                        var metadata = ModelMetadata.FromLambdaExpression<TModel, TResult>(expression, html.ViewData);
                        return MvcHtmlString.Create(metadata.SimpleDisplayText);
                    }
                }
            }
        }
        return MvcHtmlString.Create("");
    }
}

然后从你的View中调用它:

@Html.DisplayTextForCustom(x=>x.Phone)

PS:要编写此代码,我查看了Html.DisplayTextFor源代码,并尝试编写尽可能简单的代码。