【问题标题】:Visibility on and off for Html helper for model or Any editable field for model模型的 Html 助手或模型的任何可编辑字段的可见性打开和关闭
【发布时间】:2013-12-29 16:41:03
【问题描述】:

我有个模特说

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)] 之类的属性来完成?

【问题讨论】:

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


    【解决方案1】:

    所有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("");
        }
    }
    

    然后像这样从您的视图中调用它:

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

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

    【讨论】:

    • 所以在某种程度上你说我们不能只为已经存在的 html 帮助类编写属性。为了插入功能,我们必须滚动我们自己的 html 助手类?
    • 是的,因为它们与其他属性完全集成,并且它们使用模型元数据。这是viewdata.modelmetadata,你不能扩展这个类,它不是部分的。所以你应该自己做帮手。
    • 是的,我试过了。它的工作原理谢谢。但是我想知道它是否可以在没有自定义扩展的情况下使用。如果没有它本身,玩起来会更好:)
    猜你喜欢
    • 2013-05-28
    • 2014-07-10
    • 2015-04-02
    • 2013-04-13
    • 2012-08-07
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多