Iqbal Fasyah
Iqbal Fasyah

Reputation: 107

ExpressionMetadataProvider in .net core 3.1

Migrate .net core 2.2 to 3.1, I have trouble with "Microsoft.AspNetCore.Mvc.ViewFeatures". In this code, ExpressionMetadataProvider.FromLambdaExpression not support in .net core 3.1.

public static IHtmlContent CustomTextBoxFor<TModel, TProperty>(
        this IHtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression,
        object htmlAttributes
    )
    {
        var member = expression.Body as MemberExpression;
        var stringLength = member.Member
            .GetCustomAttributes(typeof(StringLengthAttribute), false)
            .FirstOrDefault() as StringLengthAttribute;

        var expresionProvider = htmlHelper.ViewContext.HttpContext.RequestServices
   .GetService(typeof(ModelExpressionProvider)) as ModelExpressionProvider;

        var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, htmlHelper.ViewData, htmlHelper.MetadataProvider);

        ModelMetadata metadata = modelExplorer.Metadata;
        string htmlFieldName = expresionProvider.GetExpressionText(expression);
        string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();

Upvotes: 2

Views: 3039

Answers (3)

dpineda
dpineda

Reputation: 2448

Here is a working version for core 9.0

    public static IHtmlContent CustomTextBoxFor<TModel, TProperty>(
        this IHtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression,
        object htmlAttributes
    )
    {
        var expresionProvider = htmlHelper.ViewContext.HttpContext.RequestServices.GetService(typeof(ModelExpressionProvider)) as ModelExpressionProvider;
        //var expresionProvider = new ModelExpressionProvider(htmlHelper.MetadataProvider);

        var exp = expresionProvider.CreateModelExpression(htmlHelper.ViewData, expression);
        var metadata = exp.ModelExplorer.Metadata;            
        var htmlFieldName = expresionProvider.GetExpressionText(expression);
        var labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
        return new HtmlString(htmlFieldName + ":" + labelText);
    }

Upvotes: 0

Don Kedero
Don Kedero

Reputation: 107

Question is about .NET Core 3.1; but I stumbled upon this because I had the same problem in .NET 6

Snippet to get the actual value

HttpContext.RequestServices.GetRequiredService<IModelExpressionProvider>().CreateModelExpression(viewData, expression).ModelExplorer.Model;

Upvotes: 2

Fei Han
Fei Han

Reputation: 27803

Migrate .net core 2.2 to 3.1, I have trouble with "Microsoft.AspNetCore.Mvc.ViewFeatures". In this code, ExpressionMetadataProvider.FromLambdaExpression not support in .net core 3.1.

From ASP.NET Core 3.0, some pubinternal APIs are updated to be truly internal, which seems cause your above issue.

And as mentioned in this github issue, it offers ModelExpressionProvider in 3.0+ that's available from DI and expose the method(s) that can return an instance of ModelExpression which is a superset for ModelExplorer that ExpressionMetadataProvider returns.

Upvotes: 1

Related Questions