web-dev-qa-db-ja.com

ASP.NET Core 3.0のExpressionHelperの代替ですか?

ASP.NET Core 2.xでは、GetExpressionTextクラスの静的メソッドExpressionHelperを使用していたIHtmlHelper<T>拡張メソッド:

using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;

public static class HtmlHelperExtensions
{
    public static string GetExpressionText<TModel, TResult>(
        this IHtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TResult>> expression)
    {
        return ExpressionHelper.GetExpressionText(expression);
    }
}

ASP.NET Core 3.0名前空間Microsoft.AspNetCore.Mvc.ViewFeatures.Internalは使用できなくなりました。したがって、コンパイラは例外をスローしています:

「ExpressionHelper」という名前は現在のコンテキストに存在しません。

ExpressionHelper機能の適切な代替品は何ですか?

11
Nenad

ModelExpressionProvider from Microsoft.AspNetCore.Mvc.ViewFeatures に使える。

メソッドGetExpressionTextExpressionHelperの同じメソッドをラップし、この Githubの問題 で説明されているように、追加のキャッシュまたは結果を追加します。

using Microsoft.AspNetCore.Mvc.ViewFeatures;

public static class HtmlHelperExtensions
{
    public static string GetExpressionText<TModel, TResult>(
        this IHtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TResult>> expression)
    {
        var expresionProvider = htmlHelper.ViewContext.HttpContext.RequestServices
            .GetService(typeof(ModelExpressionProvider)) as ModelExpressionProvider;

        return expresionProvider.GetExpressionText(expression);
    }
}
12
Nenad

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);
    }
}

覚えておくべきことは、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);
    }
    ....
}
0
Augusto Barreto