.NET 5 ASP.NET Core MVC程序集加载抛出FileNotFoundException
解决ASP.NET Core MVC程序集加载时的FileNotFoundException问题
问题原因
使用Microsoft.NET.Sdk.Web SDK的ASP.NET Core项目中,Microsoft.AspNetCore.Mvc.Core属于共享框架依赖,默认编译后不会将其复制到项目输出目录,而是在运行时从.NET共享框架中加载。但你自定义的ReaderLoadContext仅从指定目录解析依赖,无法找到共享框架中的程序集,因此在访问ExportedTypes(需要加载依赖程序集才能解析类型继承关系)时抛出文件未找到异常。
解决方案
修改自定义AssemblyLoadContext,当本地目录无法解析依赖时,回退到默认的程序集加载上下文加载共享框架依赖:
修改后的ReaderLoadContext代码
public class ReaderLoadContext : AssemblyLoadContext { private AssemblyDependencyResolver _resolver; public ReaderLoadContext(string readerLocation) { _resolver = new AssemblyDependencyResolver(readerLocation); } protected override Assembly Load(AssemblyName assemblyName) { var assembly_path = _resolver.ResolveAssemblyToPath(assemblyName); if (assembly_path != null) { return LoadFromAssemblyPath(assembly_path); } // 本地找不到时,委托给默认加载上下文处理共享框架依赖 return Default.LoadFromAssemblyName(assemblyName); } protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) { var library_path = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName); if (library_path != null) { return LoadUnmanagedDllFromPath(library_path); } return IntPtr.Zero; } }
额外优化:更可靠的ControllerBase类型判断
原代码通过BaseType.Name判断继承关系,容易出现同名类误判问题,建议改用类型匹配:
// 项目已通过SDK隐含引用Microsoft.AspNetCore.Mvc.Core,可直接获取类型 var controllerBaseType = typeof(Microsoft.AspNetCore.Mvc.ControllerBase); var target_types = assembly.ExportedTypes .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType) .ToArray();
备选方案(自包含部署)
如果需要将所有依赖打包到输出目录,可以修改项目的.csproj文件,设置自包含部署:
<PropertyGroup> <SelfContained>true</SelfContained> <RuntimeIdentifier>win-x64</RuntimeIdentifier> <!-- 根据目标平台修改,如linux-x64、osx-x64等 --> </PropertyGroup>
执行dotnet publish后,输出目录会包含所有依赖程序集,此时自定义ReaderLoadContext无需修改即可正常解析依赖,但包体积会显著增大。
内容的提问来源于stack exchange,提问作者Léster
相关产品推荐
相关产品推荐

