【问题标题】:Accessing attributes from Custom Html Helpers in asp.net mvc 4 razor从 asp.net mvc 4 razor 中的自定义 Html Helpers 访问属性
【发布时间】:2012-06-13 18:32:26
【问题描述】:

我在 ASP.NET MVC 4 razor 视图引擎 C# 中创建了 HtmlHelper。
我可以将视图模型属性传递给我的助手类吗?
例如,我有财产

[Required]
[Display(Name = "Your Lastname")]
public string Lastname { get; set; }

我是否可以将此属性传递给我的助手,例如 @Html.Example(model => model.Lastname),然后在助手中获取数据注释(如果需要此字段,显示名称等是什么)?

【问题讨论】:

    标签: c# razor html-helper asp.net-mvc-4


    【解决方案1】:

    [Display] 属性丰富了元数据。因此,您可以从元数据中获取信息。

    例如,如果您想在帮助程序中检索显示名称:

    public static class HtmlHelpers
    {
        public static IHtmlString Example<TModel, TProperty>(
            this HtmlHelper<TModel> html, 
            Expression<Func<TModel, TProperty>> ex
        )
        {
            var metadata = ModelMetadata.FromLambdaExpression(ex, html.ViewData);
            var displayName = metadata.DisplayName;
            return new HtmlString(html.Encode(displayName));
        }
    }
    

    如果我们假设你有一个视图模型:

    public class MyViewModel
    {
        [Required]
        [Display(Name = "Your Lastname")]
        public string Lastname { get; set; }
    }
    

    您可以在强类型视图中使用帮助器:

    @model MyViewModel
    
    @Html.Example(x => x.Lastname)
    

    现在假设您编写了一个自定义元数据属性:

    public class FooBarAttribute : Attribute, IMetadataAware
    {
        public FooBarAttribute(string bar)
        {
            Bar = bar;
        }
        public string Bar { get; private set; }
    
        public void OnMetadataCreated(ModelMetadata metadata)
        {
            metadata.AdditionalValues["foo"] = Bar;
        }
    }
    

    你用来装饰你的模型的:

    public class MyViewModel
    {
        [Required]
        [FooBar("This is the bar")]
        public string SomeBar { get; set; }
    }
    

    然后在你的助手中你可以获取自定义属性:

    public static class HtmlHelpers
    {
        public static IHtmlString Example<TModel, TProperty>(
            this HtmlHelper<TModel> html, 
            Expression<Func<TModel, TProperty>> ex
        )
        {
            var metadata = ModelMetadata.FromLambdaExpression(ex, html.ViewData);
            if (metadata.AdditionalValues.ContainsKey("foo"))
            {
                var foo = metadata.AdditionalValues["foo"] as string;
                return new HtmlString(html.Encode(foo));
            }
            return MvcHtmlString.Empty;
        }
    }
    

    更新:

    您似乎需要获取Required 消息。不知道为什么需要在自定义帮助程序中执行此操作,但这里有一个示例,您可以如何实现这一点:

    public static class HtmlHelpers
    {
        public static IHtmlString Example<TModel, TProperty>(
            this HtmlHelper<TModel> html, 
            Expression<Func<TModel, TProperty>> ex
        )
        {
            var me = (ex.Body as MemberExpression);
            if (me != null)
            {
                var required = me
                    .Member
                    .GetCustomAttributes(typeof(RequiredAttribute), false)
                    .Cast<RequiredAttribute>()
                    .FirstOrDefault();
                if (required != null)
                {
                    var msg = required.FormatErrorMessage(me.Member.Name);
                    return new HtmlString(html.Encode(msg));
                }
            }
            return MvcHtmlString.Empty;
        }
    }
    

    【讨论】:

    • 哇。我觉得你很棒:)谢谢你
    • 你能说我如何找到需要数据验证的消息吗?我想得到这个消息 >>> data-val-date="该字段 BirthDate 必须是一个日期。" data-val-required="BirthDate 字段为必填项。
    • data-val-required 是客户端属性。我猜您想获取Required 属性使用的消息。我会用一个例子来更新我的答案。
    • 谢谢,获得所需消息是我需要为模型属性构建自己的自定义 DateTimePicker 的东西。我需要知道是否有一个必需的属性来为 data-val 添加标记为真,然后使用 required 消息来设置 data-val-required 。因此,我的扩展助手无需任何额外工作即可进行验证。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 2012-09-13
    • 2011-07-19
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多