C#在静态上下文中访问IModelMetaDataProvider - IHtmlHelper

时间:2017-09-30 10:41:46

标签: c# .net asp.net-core

我正在探索实现自定义复选框助手的方法,我可以将其用于Razor视图。该应用程序正在使用Microsoft.AspNetCore 2.0.0。您已尝试自定义TagHelper解决方案和IHtmlHelper的静态扩展方法。

不幸的是,该项目最初是MVC5,有一些需要移植的传统MVC5静态助手。

有问题的方法调用是arg [2]:

    ModelExplorer metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, (ViewDataDictionary<TModel>)html.ViewData, [I need to resolve and pass in IModelMetadataProvider here]);

以下是帮助程序的基本代码

    public static IHtmlContent MvcCheckBoxFor<TModel, TResult>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TResult>> expression, object htmlAttributes = null)
    {

        // see http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/5cb74eb3b2f3#src/System.Web.Mvc/Html/InputExtensions.cs this applies the correct "name" HTMl attribute

        if (expression == null)
        {
            throw new ArgumentNullException("expression");
        }


        // TODO: Resolve IModelMetedataProvider - argument 3 - left null 
        ModelExplorer metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, (ViewDataDictionary<TModel>)html.ViewData, null);


        bool isChecked = false;
        if (metadata.Model != null)
        {
            bool modelChecked;
            if (Boolean.TryParse(metadata.Model.ToString(), out modelChecked))
            {
                isChecked = modelChecked;
            }
        }

        string fullName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(expression));

        return CheckBoxHelper(fullName, fullName, isChecked, htmlAttributes);
    }

我省略了CheckBoxHelper代码,因为功能超出了问题的范围。签名如下:

 private static IHtmlContent CheckBoxHelper(string name, string id, bool isChecked, object htmlAttributes)

实现.NET 4.5.2调用的旧方法是:

 ModelMetadata.FromLambdaExpression(expression, html.ViewData);

签名和命名空间已从System.Web.Mvc更改为Microsoft.AspNetCore.Mvc.ViewFeatures.Internal

只是想知道我可以使用什么策略来进行此调用。 MSFT的助手如@Html.LabelFor必须做一些事情 - 它们也处于静态环境中。

Activator.CreateInstance<IModelMetadataProvider>()可用但不可行,因为您无法创建接口实例。是否有具体的类型或解决方法?

任何帮助都会非常感激。

非常感谢您花时间阅读本文,

约翰

1 个答案:

答案 0 :(得分:2)

只需浏览IHtmlHelper代码 - 有一个IModelMetadataProvider只读字段。

所以,

html.MetadataProvider

解决它。我觉得很傻。非常感谢MSFT的加入!