C# 是否替换ASP.NET Core 3.0中的ExpressionHelper?

C# 是否替换ASP.NET Core 3.0中的ExpressionHelper?,c#,asp.net-core,asp.net-core-3.0,C#,Asp.net Core,Asp.net Core 3.0,在ASP.NET Core 2.x中,我使用了ExpressionHelper类的静态方法GetExpressionText,用于IHtmlHelper扩展方法: 使用Microsoft.AspNetCore.Mvc.ViewFeatures.Internal; 公共静态类HtmlHelperExtensions { 公共静态字符串GetExpressionText( 这个IHtmlHelper htmlHelper, 表达式(表达式) { 返回ExpressionHelper.GetExpre

在ASP.NET Core 2.x中,我使用了
ExpressionHelper
类的静态方法
GetExpressionText
,用于
IHtmlHelper
扩展方法:

使用Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
公共静态类HtmlHelperExtensions
{
公共静态字符串GetExpressionText(
这个IHtmlHelper htmlHelper,
表达式(表达式)
{
返回ExpressionHelper.GetExpressionText(表达式);
}
}
在ASP.NET Core 3.0命名空间中,Microsoft.AspNetCore.Mvc.ViewFeatures.Internal不再可用。因此,编译器正在引发异常:

当前上下文中不存在名称“ExpressionHelper”


什么是ExpressionHelper功能的正确替代品?

可以使用Microsoft.AspNetCore.Mvc.ViewFeatures中的
ModelExpressionProvider


方法
GetExpressionText
包装了与
ExpressionHelper
相同的方法,并添加了额外的缓存或结果,如本文所述

使用Microsoft.AspNetCore.Mvc.ViewFeatures;
公共静态类HtmlHelperExtensions
{
公共静态字符串GetExpressionText(
这个IHtmlHelper htmlHelper,
表达式(表达式)
{
var expresionProvider=htmlHelper.ViewContext.HttpContext.RequestServices
.GetService(typeof(ModelExpressionProvider))作为ModelExpressionProvider;
返回ExpressionProvider.GetExpressionText(表达式);
}
}

不依赖IHtmlHelper且可用于其他场景的替代解决方案如下:

public static class StringExtensions
{
    private static readonly ModelExpressionProvider ModelExpressionProvider = new ModelExpressionProvider(new EmptyModelMetadataProvider());

    public static string GetExpressionText<TEntity, TProperty>(this Expression<Func<TEntity, TProperty>> expression)
    {
        return ModelExpressionProvider.GetExpressionText(expression);
    }
}
公共静态类StringExtensions
{
私有静态只读ModelExpressionProvider ModelExpressionProvider=new ModelExpressionProvider(new EmptyModelMetadataProvider());
公共静态字符串GetExpressionText(此表达式)
{
返回ModelExpressionProvider.GetExpressionText(表达式);
}
}
需要记住的是ModelExpressionProvider内部有一个用于缓存的ConcurrentDictionary,这就是为什么使其成为静态可能是有益的

正如Nenad所说,ModelExpressionProvider.GetExpressionText只是ExpressionHelper.GetExpressionText的包装,添加了缓存参数:

public class ModelExpressionProvider : IModelExpressionProvider
{
    private readonly IModelMetadataProvider _modelMetadataProvider;
    private readonly ConcurrentDictionary<LambdaExpression, string> _expressionTextCache;
    ....
    public string GetExpressionText<TModel, TValue>(Expression<Func<TModel, TValue>> expression)
    {
        if (expression == null)
        {
            throw new ArgumentNullException(nameof(expression));
        }

        return ExpressionHelper.GetExpressionText(expression, _expressionTextCache);
    }
    ....
}
公共类ModelExpressionProvider:IModeExpressionProvider
{
私有只读IModelMetadataProvider\u modelMetadataProvider;
私有只读ConcurrentDictionary\u expressionTextCache;
....
公共字符串GetExpressionText(表达式)
{
if(表达式==null)
{
抛出新ArgumentNullException(nameof(expression));
}
返回ExpressionHelper.GetExpressionText(表达式,_expressionTextCache);
}
....
}

如果不使用视图,这是否有效?比如API。我不知道为什么
GetExpressionText
需要任何类型的ViewContext
GetExpressionText
主要用于呈现HTML元素ID和名称以进行模型绑定,因此IHtmlHelper的扩展适用于大多数用例。您也可以从API使用它。您只需获得
ModelExpressionProvider
的实例。最简单的可能是通过控制器构造函数中的依赖项注入来获得它。谢谢。我的用例稍微复杂一点。我真的需要一个汽车制造商的档案。不幸的是,通过内置程序集扫描注册的配置文件不支持注入内容。它们必须有一个空构造函数。因此,我刚刚找到了其他代码片段来完成我需要做的事情,这实际上是将表达式属性链转换为比getexpressiontext更简单的字符串。