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