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

ASP.NET Core发布至IIS后出现BadImageFormatException程序集加载错误如何解决?

解决ASP.NET Core发布至IIS后加载系统DLL引发的BadImageFormatException问题

这个问题我之前也碰到过,根源就是你的代码遍历了发布目录下所有.dll文件,其中包含了Windows系统的API集DLL(比如api-ms-win-core-console-l1-1-0.dll这类)——这些是原生系统库,根本不是.NET程序集,强行用Assembly.Load加载肯定会抛出异常。下面给你几个针对性的解决方案,按推荐程度排序:

方案1:过滤已知的系统非.NET DLL

直接在获取文件路径时,排除那些明显是系统原生库的文件名,比如api-ms-win-开头的,还有CLR运行时的原生组件:

public static List<Type> FromAssembliesMatching<TType>(this AppDomain currentDomain, string searchPattern)
{
    var referencedPaths = Directory.GetFiles(currentDomain.BaseDirectory, "*.dll")
        // 排除系统原生DLL
        .Where(path => 
            !Path.GetFileName(path).StartsWith("api-ms-win-", StringComparison.OrdinalIgnoreCase) &&
            !Path.GetFileName(path).Equals("clrcompression.dll", StringComparison.OrdinalIgnoreCase) &&
            !Path.GetFileName(path).Equals("clrjit.dll", StringComparison.OrdinalIgnoreCase) &&
            !Path.GetFileName(path).Equals("Microsoft.Windows.Common-Controls.dll", StringComparison.OrdinalIgnoreCase))
        .ToList();

    var assemblies = referencedPaths
        .Select(path => currentDomain.Load(AssemblyName.GetAssemblyName(path)))
        .ToList();

    var types = assemblies.SelectMany(s => s.GetTypes()
            .Where(t => typeof(TType).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract))
        .ToList();

    return types;
}

方案2:结合Try-Catch容错,跳过加载失败的DLL

有些系统DLL的文件名可能不在上面的过滤列表里,这时可以在加载程序集时用try-catch捕获异常,直接跳过无法加载的文件:

public static List<Type> FromAssembliesMatching<TType>(this AppDomain currentDomain, string searchPattern)
{
    var referencedPaths = Directory.GetFiles(currentDomain.BaseDirectory, "*.dll").ToList();
    var assemblies = new List<Assembly>();

    foreach (var path in referencedPaths)
    {
        try
        {
            var assemblyName = AssemblyName.GetAssemblyName(path);
            assemblies.Add(currentDomain.Load(assemblyName));
        }
        catch (BadImageFormatException)
        {
            // 跳过非.NET程序集
            continue;
        }
        catch (FileLoadException)
        {
            // 跳过已加载或无法加载的程序集
            continue;
        }
    }

    var types = assemblies.SelectMany(s => s.GetTypes()
            .Where(t => typeof(TType).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract))
        .ToList();

    return types;
}

方案3:只加载你的应用相关程序集(最推荐)

如果你的应用程序集有统一的命名规则(比如都以YourCompany.或YourApp.开头),可以直接根据程序集名称过滤,只加载你自己的业务程序集和依赖的第三方.NET库,完全避免碰系统DLL:

public static List<Type> FromAssembliesMatching<TType>(this AppDomain currentDomain, string searchPattern)
{
    var referencedPaths = Directory.GetFiles(currentDomain.BaseDirectory, "*.dll").ToList();
    var assemblies = new List<Assembly>();

    foreach (var path in referencedPaths)
    {
        try
        {
            var assemblyName = AssemblyName.GetAssemblyName(path);
            // 只加载你的应用程序集和信任的第三方库
            if (assemblyName.FullName.StartsWith("YourApp.") || 
                assemblyName.FullName.StartsWith("Newtonsoft.Json") ||
                assemblyName.FullName.StartsWith("AutoMapper"))
            {
                assemblies.Add(currentDomain.Load(assemblyName));
            }
        }
        catch (Exception)
        {
            continue;
        }
    }

    var types = assemblies.SelectMany(s => s.GetTypes()
            .Where(t => typeof(TType).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract))
        .ToList();

    return types;
}

额外提示

在ASP.NET Core中,其实还有更优雅的方式来发现接口实现类——比如利用依赖注入的IServiceCollection,或者使用AssemblyLoadContext来安全地加载程序集,避免直接遍历所有DLL的粗暴方式。不过上面的方案已经能快速解决你当前的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:38:13