.NET自定义强类型HTML帮助程序,具有深层属性导航

时间:2013-07-22 22:22:47

标签: .net asp.net-mvc-4 html-helper modelmetadata

我四处搜索,阅读了与创建强类型帮助器相关的所有帖子,但没有一个解决了我的问题。问题:

引用简单属性时,一切运行良好:

@Html.TextBoxGroupFor(x => x.BadgeNumber)

当我尝试访问模型中不同类的属性时,出现错误:

@Html.TextBoxGroupFor(x => x.Person.BadgeNumber)

错误是:

找不到属性InspectionEditViewModel.Person.BadgeNumber。

问题在于:

var metaData = ModelMetadataProviders.Current.GetMetadataForProperty(() => Activator.CreateInstance<TModel>(), typeof(TModel), displayName);

我猜测它与GetMetadataForProperty无法在InspectionEditViewModel上找到BadgeNumber有关。默认情况下,MVC的HTML帮助程序可以毫无问题地执行此操作。

编辑:

我知道我遗漏了一些东西,这是漫长的一天。这是助手代码:

public static MvcHtmlString TextBoxGroupFor<TModel, TProperty>(this HtmlHelper<TModel> helper,
                                                     Expression<Func<TModel, TProperty>> expression)
        {
            var inputName = ExpressionHelper.GetExpressionText(expression);
            var fullHtmlFieldName = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(inputName);
            var metaData = ModelMetadataProviders.Current.GetMetadataForProperty(() => Activator.CreateInstance<TModel>(), typeof(TModel), fullHtmlFieldName);
            var displayName = metaData.DisplayName ?? inputName;
            return TextBoxGroup(helper, displayName, inputName);
        }

1 个答案:

答案 0 :(得分:1)

ModelMetadata.FromLambdaExpression(propertyExpression, html.ViewData);

这就是你要找的东西。不幸的是,这意味着html必须是来自视图的HtmlHelper实例,其模型是您尝试获取元数据的类型。

我认为这是因为它希望从Model / ViewData获取属性值并通过ModelMetadataProvider传递它,以允许它填充特定于相关模型实例的元数据。

如果您不关心特定于实例的元数据(例如:只需要数据注释属性)等等,那么只需传递一个新的ViewDataDictionary(其中TModel是您想要获取其元数据的类型)。

对于奖励感觉良好的点,FromLambdaExpression方法将表达式及其解析的属性路径缓存在其中以提供更好的性能。

希望对你有所帮助。