You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Microsoft.AspNetCore.Mvc.ViewFeatures时遇TypeLoadException类型加载错误

解决TypeLoadException:无法加载ExpressionMetadataProvider类型

你在ASP.NET Core项目中使用自定义HTML Helper生成Alert组件时,遇到了类型加载异常,相关代码及错误信息如下:

视图页面代码

@using MyHelpers
@model FluentHtmlHelpers.Models.SampleAlertModel

@{
    ViewBag.Title = "Strongly Typed";
}

<h2>Strongly Typed</h2>
<span>Html.AlertFor(m => m.AlertBoxText).Success()</span>
@Html.AlertFor(m => m.AlertBoxText).Success()

<span>Html.AlertFor(m => m.AlertBoxText, m => m.AlertBoxStyle)</span>
@Html.AlertFor(m => m.AlertBoxText, m => m.AlertBoxStyle)

模型类代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MyHelpers;

namespace FluentHtmlHelpers.Models
{
    public class SampleAlertModel
    {
        public string AlertBoxText { get; set; }
        public MyHelpers.AlertStyle AlertBoxStyle { get; set; }
    }
}

自定义AlertHtmlHelper代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc;

using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;

namespace MyHelpers
{
    /// <summary>
    /// Generates an Alert message
    /// </summary>
    public static class AlertHtmlHelper
    {
        /// <summary>
        /// Generates an Alert message
        /// </summary>
        public static AlertBox Alert(this IHtmlHelper html,
            string text,
            AlertStyle alertStyle = AlertStyle.Default,
            bool hideCloseButton = false,
            object htmlAttributes = null)
        {
            return new AlertBox(text, alertStyle, hideCloseButton, htmlAttributes);
        }

        // Strongly typed
        /// <summary>
        /// Generates an Alert message
        /// </summary>
        public static AlertBox AlertFor<TModel, TTextProperty>(this IHtmlHelper<TModel> html,
            Expression<Func<TModel, TTextProperty>> expression,
            AlertStyle alertStyle = AlertStyle.Default,
            bool hideCloseButton = false,
            object htmlAttributes = null)
        {
            var metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider);
            return new AlertBox((string)metadata.Model, alertStyle, hideCloseButton, htmlAttributes);
        }

        /// <summary>
        /// Generates an Alert message
        /// </summary>
        public static AlertBox AlertFor<TModel, TTextProperty, TStyleProperty>(this IHtmlHelper<TModel> html,
            Expression<Func<TModel, TTextProperty>> textExpression,
            Expression<Func<TModel, TStyleProperty>> styleExpression,
            bool hideCloseButton = false,
            object htmlAttributes = null)
        {
            var text = (string) ExpressionMetadataProvider.FromLambdaExpression(textExpression, html.ViewData, html.MetadataProvider).Model;
            var alertStyle = (AlertStyle)ExpressionMetadataProvider.FromLambdaExpression(styleExpression, html.ViewData, html.MetadataProvider).Model;

            return new AlertBox(text, alertStyle,hideCloseButton, htmlAttributes);
        }
    }
}

抛出的错误信息

TypeLoadException: 无法从程序集'Microsoft.AspNetCore.Mvc.ViewFeatures, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'中加载类型'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ExpressionMetadataProvider'。


解决方案

原因分析

ASP.NET Core 8.0中,Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ExpressionMetadataProvider这个内部类型被调整为公开命名空间下的可用类型,不再允许直接引用Internal命名空间内的类型。

修改步骤

  1. 移除内部命名空间引用:删除代码中using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;这一行。
  2. 替换元数据获取方式:使用IHtmlHelper提供的GetModelMetadataFromExpression扩展方法,或者直接调用公开的ExpressionMetadataProvider类方法。

修改后的AlertHtmlHelper代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;

namespace MyHelpers
{
    /// <summary>
    /// Generates an Alert message
    /// </summary>
    public static class AlertHtmlHelper
    {
        /// <summary>
        /// Generates an Alert message
        /// </summary>
        public static AlertBox Alert(this IHtmlHelper html,
            string text,
            AlertStyle alertStyle = AlertStyle.Default,
            bool hideCloseButton = false,
            object htmlAttributes = null)
        {
            return new AlertBox(text, alertStyle, hideCloseButton, htmlAttributes);
        }

        // Strongly typed
        /// <summary>
        /// Generates an Alert message
        /// </summary>
        public static AlertBox AlertFor<TModel, TTextProperty>(this IHtmlHelper<TModel> html,
            Expression<Func<TModel, TTextProperty>> expression,
            AlertStyle alertStyle = AlertStyle.Default,
            bool hideCloseButton = false,
            object htmlAttributes = null)
        {
            // 使用IHtmlHelper扩展方法获取元数据
            var metadata = html.GetModelMetadataFromExpression(expression);
            return new AlertBox((string)metadata.Model, alertStyle, hideCloseButton, htmlAttributes);
        }

        /// <summary>
        /// Generates an Alert message
        /// </summary>
        public static AlertBox AlertFor<TModel, TTextProperty, TStyleProperty>(this IHtmlHelper<TModel> html,
            Expression<Func<TModel, TTextProperty>> textExpression,
            Expression<Func<TModel, TStyleProperty>> styleExpression,
            bool hideCloseButton = false,
            object htmlAttributes = null)
        {
            var textMetadata = html.GetModelMetadataFromExpression(textExpression);
            var styleMetadata = html.GetModelMetadataFromExpression(styleExpression);

            var text = (string)textMetadata.Model;
            var alertStyle = (AlertStyle)styleMetadata.Model;

            return new AlertBox(text, alertStyle, hideCloseButton, htmlAttributes);
        }
    }
}

补充说明

如果项目中没有GetModelMetadataFromExpression扩展方法,也可以直接调用公开的ExpressionMetadataProvider方法(无需Internal命名空间),调用逻辑和原代码一致:

var metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider);

只需确保移除Microsoft.AspNetCore.Mvc.ViewFeatures.Internal的引用即可,当前版本中ExpressionMetadataProvider已在Microsoft.AspNetCore.Mvc.ViewFeatures命名空间下公开可用。

内容的提问来源于stack exchange,提问作者redoc01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:15:03