从Lambda Property Expression获取自定义属性

我正在使用ASP.NET MVC 2 Preview 2并编写了一个自定义的HtmlHelper扩展方法来使用表达式创建标签。 TModel来自具有属性的简单类,属性可以具有定义validation要求的属性。 我试图找出表达式在我的label方法中表示的属性上是否存在某个属性。

类和标签的代码是:

public class MyViewModel { [Required] public string MyProperty { get; set; } } public static MvcHtmlString Label(this HtmlHelper htmlHelper, Expression<Func> expression, string label) { return MvcHtmlString.Create(string.Concat("")); } public static string GetInputName(this Expression<Func> expression) { return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1); } 

然后我会像这样称呼标签:

 Html.Label(x => x.MyProperty, "My Label") 

有没有办法找出传递给Label方法的表达式值中的属性是否具有Required属性?

我发现如果它存在,执行以下操作确实可以获得属性,但我希望有一种更简洁的方法来实现这一点。

 public static MvcHtmlString Label(this HtmlHelper htmlHelper, Expression<Func> expression, string label) { System.Attribute.GetCustomAttribute(Expression.Property(Expression.Parameter(expression.Parameters[0].Type, expression.GetInputName()), expression.GetInputName()).Member, typeof(RequiredAttribute)) return MvcHtmlString.Create(string.Concat("")); } 

你的表达式解析逻辑可以使用一些工作。 您将转换为字符串,而不是处理实际类型。

以下是您可以使用的一组扩展方法。 第一个获取成员的名称。 第二个/第三个组合以检查属性是否在成员上。 GetAttribute将返回请求的属性或null,IsRequired只检查该特定属性。

 public static class ExpressionHelpers { public static string MemberName(this Expression> expression) { var memberExpression = expression.Body as MemberExpression; if (memberExpression == null) throw new InvalidOperationException("Expression must be a member expression"); return memberExpression.Member.Name; } public static T GetAttribute(this ICustomAttributeProvider provider) where T : Attribute { var attributes = provider.GetCustomAttributes(typeof(T), true); return attributes.Length > 0 ? attributes[0] as T : null; } public static bool IsRequired(this Expression> expression) { var memberExpression = expression.Body as MemberExpression; if (memberExpression == null) throw new InvalidOperationException("Expression must be a member expression"); return memberExpression.Member.GetAttribute() != null; } } 

希望这会帮助你。

这段代码怎么样(来自codeplex上的MVC项目)

 public static bool IsRequired(this Expression> expression, HtmlHelper htmlHelper) { var modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(expression)); FieldValidationMetadata fieldMetadata = ApplyFieldValidationMetadata(htmlHelper, modelMetadata, modelName); foreach (var item in fieldMetadata.ValidationRules) { if (item.ValidationType == "required") return true; } return false; } private static FieldValidationMetadata ApplyFieldValidationMetadata(HtmlHelper htmlHelper, ModelMetadata modelMetadata, string modelName) { FormContext formContext = htmlHelper.ViewContext.FormContext; FieldValidationMetadata fieldMetadata = formContext.GetValidationMetadataForField(modelName, true /* createIfNotFound */); // write rules to context object IEnumerable validators = ModelValidatorProviders.Providers.GetValidators(modelMetadata, htmlHelper.ViewContext); foreach (ModelClientValidationRule rule in validators.SelectMany(v => v.GetClientValidationRules())) { fieldMetadata.ValidationRules.Add(rule); } return fieldMetadata; }