扩展IHtmlHelper:如何在自定义MyEditorFor中获取属性的DataTypeAttribute
解决自定义Html.EditorFor无需传入containerType获取DataTypeAttribute的方案
核心思路是直接解析传入的表达式树,而非依赖绑定名称和容器类型。表达式树本身包含了属性的完整访问路径,通过遍历解析可以直接定位到目标属性,进而获取其DataTypeAttribute。
修改后的实现代码
public static IHtmlContent MyEditorFor<TModel, TResult>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TResult>> expression, object moreData) { // 解析表达式树,获取目标属性的PropertyInfo var targetProperty = GetTargetProperty(expression.Body); var dataType = GetDataTypeFromProperty(targetProperty); // 保留原有绑定名称逻辑 var ep = html.ViewContext.HttpContext.RequestServices.GetService(typeof(ModelExpressionProvider)) as ModelExpressionProvider; var bindName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ep.GetExpressionText(expression)); // 后续业务逻辑... } // 递归解析表达式树,提取最终的目标属性 private static PropertyInfo? GetTargetProperty(Expression expression) { // 处理可空类型的装箱转换表达式 if (expression is UnaryExpression unaryExpr && unaryExpr.NodeType == ExpressionType.Convert) { return GetTargetProperty(unaryExpr.Operand); } // 处理集合索引访问(如LinkedTable[i]),跳过索引节点继续解析后续属性 if (expression is IndexExpression indexExpr) { return GetTargetProperty(indexExpr.Object); } // 处理成员访问表达式,直接返回属性信息 if (expression is MemberExpression memberExpr && memberExpr.Member is PropertyInfo prop) { return prop; } // 无法解析时返回null return null; } // 从PropertyInfo中提取DataType枚举值 private static DataType GetDataTypeFromProperty(PropertyInfo? property) { if (property == null) return DataType.Text; var dataTypeAttr = property.GetCustomAttribute<DataTypeAttribute>(); return dataTypeAttr?.DataType ?? DataType.Text; }
关键改动说明
- 移除containerType参数:不再需要手动传入容器类型,所有属性信息通过表达式树解析自动获取。
- 表达式树解析逻辑:
- 适配可空类型的
UnaryExpression场景,避免因装箱转换导致的解析失败。 - 处理集合索引访问的
IndexExpression,跳过索引节点后继续解析后续的属性访问路径。 - 直接从
MemberExpression中提取目标属性的PropertyInfo。
- 适配可空类型的
- 简化特性获取:通过泛型方法
GetCustomAttribute<DataTypeAttribute>直接获取特性,替代原有的反射遍历逻辑,代码更简洁高效。
使用示例
现在调用时无需传入容器类型参数,直接使用:
@Html.MyEditorFor(x => x.LinkedTable[i].MyDate, new { placeholder = "Test Date" })
内容的提问来源于stack exchange,提问作者puzzler
相关产品推荐
相关产品推荐

