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

.NET5加载ASP.NET Core WebApi程序集缺失Microsoft相关库问题咨询

为什么依赖文件不会自动复制到输出文件夹

从.NET Core 3.0开始,ASP.NET Core相关的核心程序集都被整合进了共享框架(Shared Framework),默认不会作为独立Nuget包被复制到项目输出目录,运行时会从系统级的共享框架安装路径加载这些依赖。你单独安装Microsoft.AspNetCore.Mvc.Core这类Nuget包也不会触发本地复制,因为这些包本质上只是指向共享框架的引用包,不包含实际的可执行二进制内容。
如果要强制WebApi项目输出所有依赖,只需要在WebApi项目的.csproj文件的<PropertyGroup>节点下添加配置:

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

重新编译后所有相关依赖都会输出到bin目录。

如何正确读取已编译WebApi的控制器方法,现有实现的问题

现有实现的问题

你现在用Assembly.LoadFrom的方式需要加载目标程序集的全部依赖才能正常读取类型,一旦依赖不在当前程序的探测路径里就会抛出加载失败异常,这个方案的兼容性很差,尤其是面对基于共享框架编译的.NET 5+项目。

正确的实现方案

推荐用元数据读取的方式,不需要加载完整程序集,也不需要依赖目标程序的任何运行时依赖,就能直接提取控制器和方法信息。你可以使用System.Reflection.Metadata库实现:

  1. 先通过Nuget安装System.Reflection.Metadata包
  2. 示例代码如下:
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;

var assemblyPath = @"你的WebApi dll路径";
using var stream = File.OpenRead(assemblyPath);
using var peReader = new PEReader(stream);
var metadataReader = peReader.GetMetadataReader();

// 遍历所有类型
foreach (var typeDefHandle in metadataReader.TypeDefinitions)
{
    var typeDef = metadataReader.GetTypeDefinition(typeDefHandle);
    var typeName = metadataReader.GetString(typeDef.Name);
    var namespaceName = metadataReader.GetString(typeDef.Namespace);
    
    // 判断是否是控制器:通常是继承自ControllerBase,且名称以Controller结尾
    bool isController = false;
    // 遍历基类判断是否是ControllerBase
    if (typeDef.BaseType.Kind == HandleKind.TypeReference)
    {
        var baseTypeRef = metadataReader.GetTypeReference((TypeReferenceHandle)typeDef.BaseType);
        var baseTypeName = metadataReader.GetString(baseTypeRef.Name);
        if (baseTypeName is "ControllerBase" or "Controller")
        {
            isController = true;
        }
    }
    if (!isController) continue;
    
    Console.WriteLine($"找到控制器:{namespaceName}.{typeName}");
    // 遍历控制器的所有公共方法
    foreach (var methodDefHandle in typeDef.GetMethods())
    {
        var methodDef = metadataReader.GetMethodDefinition(methodDefHandle);
        // 只取公共实例方法
        if (methodDef.Attributes.HasFlag(MethodAttributes.Public) && !methodDef.Attributes.HasFlag(MethodAttributes.Static))
        {
            var methodName = metadataReader.GetString(methodDef.Name);
            Console.WriteLine($"  方法:{methodName}");
        }
    }
}

这种方式完全不需要依赖目标WebApi的任何运行时程序集,不会出现缺失dll的报错,兼容性覆盖.NET Core 3.1到.NET 8的所有版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:45:02