web-dev-qa-db-fra.com

Remplacement d'ExpressionHelper dans ASP.NET Core 3.0?

Dans ASP.NET Core 2.x, j'utilisais la méthode statique GetExpressionText de ExpressionHelper classe pour IHtmlHelper<T> méthode d'extension:

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

Dans l'espace de noms ASP.NET Core 3.0 Microsoft.AspNetCore.Mvc.ViewFeatures.Internal n'est plus disponible. Par conséquent, le compilateur lève une exception:

Le nom "ExpressionHelper" n'existe pas dans le contexte actuel.

Quel est le remplacement approprié de la fonctionnalité ExpressionHelper?

11
Nenad

ModelExpressionProvider de Microsoft.AspNetCore.Mvc.ViewFeatures peut être utilisé.

La méthode GetExpressionText encapsule la méthode identique de ExpressionHelper et ajoute une mise en cache ou des résultats supplémentaires comme décrit dans ce problème 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

Une solution alternative qui ne dépend pas d'IHtmlHelper et qui peut être utilisée dans d'autres scénarios est la suivante:

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

Il convient de garder à l'esprit que ModelExpressionProvider contient un ConcurrentDictionary à l'intérieur pour la mise en cache, c'est pourquoi le rendre statique pourrait être bénéfique.

Comme l'a dit Nenad, ModelExpressionProvider.GetExpressionText n'est qu'un wrapper autour d'ExpressionHelper.GetExpressionText avec l'ajout du paramètre de cache:

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