.NET 8 Blazor(MudBlazor)部署IIS随机出现FileNotFoundException问题
随机出现的Microsoft.Extensions.Localization加载异常排查与解决(.NET 8 + MudBlazor + IIS)
问题描述
开发的基于.NET 8、使用MudBlazor的Blazor应用部署在IIS服务器上,本地和开发环境运行正常,但生产环境随机抛出以下异常:
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.Localization, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified. File name: 'Microsoft.Extensions.Localization, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' at MudBlazor.AbstractLocalizationInterceptor.DefaultLanguageResourceReader(ILoggerFactory loggerFactory) at MudBlazor.AbstractLocalizationInterceptor..ctor(ILoggerFactory loggerFactory, MudLocalizer mudLocalizer) at MudBlazor.DefaultLocalizationInterceptor..ctor(ILoggerFactory loggerFactory, MudLocalizer mudLocalizer) at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor) at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr) at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) at Microsoft.AspNetCore.Components.ComponentFactory.<>c__DisplayClass9_0.<CreatePropertyInjector>g__Initialize|1(IServiceProvider serviceProvider, IComponent component) at Microsoft.AspNetCore.Components.ComponentFactory.InstantiateComponent(IServiceProvider serviceProvider, Type componentType, IComponentRenderMode callerSpecifiedRenderMode, Nullable`1 parentComponentId) at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateChildComponentOnFrame(RenderTreeFrame[] frames, Int32 frameIndex, Int32 parentComponentId) at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& diffContext, Int32 frameIndex) at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& diffContext, Int32 frameIndex) at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex) at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl) at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, Int32 componentId, ArrayRange`1 oldTree, ArrayRange`1 newTree) at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException) at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry) at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.HandleException(Exception exception) at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue() at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessPendingRender() at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment) at Microsoft.AspNetCore.Components.RenderHandle.Render(RenderFragment renderFragment) at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged() at Microsoft.AspNetCore.Components.ComponentBase.CallOnParametersSetAsync() at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync() at Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.HandleException(Exception exception) at Microsoft.AspNetCore.Components.RenderTree.Renderer.HandleExceptionViaErrorBoundary(Exception error, ComponentState errorSourceOrNull) at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToPendingTasksWithErrorHandling(Task task, ComponentState owningComponentState) at Microsoft.AspNetCore.Components.Rendering.ComponentState.SupplyCombinedParameters(ParameterView directAndCascadingParameters) at Microsoft.AspNetCore.Components.Rendering.ComponentState.SetDirectParameters(ParameterView parameters) at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderRootComponentAsync(Int32 componentId, ParameterView initialParameters) at Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.BeginRenderingComponent(IComponent component, ParameterView initialParameters) at Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.BeginRenderingComponent(Type componentType, ParameterView initialParameters) at Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.RenderEndpointComponent(HttpContext httpContext, Type rootComponentType, ParameterView parameters, Boolean waitForQuiescence) at Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context) at Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context) at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c.<<InvokeAsync>b__10_0>d.MoveNext() --- End of stack trace from previous location --- at Program.<>c__DisplayClass0_1.<<<Main>$>b__5>d.MoveNext() in E:\agent-cs\_work\153\s\*****\Program.cs:line 107 --- End of stack trace from previous location --- at Program.<>c.<<<Main>$>b__0_3>d.MoveNext() in E:\agent-cs\_work\153\s\*****\Program.cs:line 105 --- End of stack trace from previous location --- at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.<Invoke>g__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)
已知信息
- 部署目录中已存在
Microsoft.Extensions.Localization.dll - 本地无法复现问题,重新部署相同代码包后生产环境恢复正常
- 各环境IIS站点配置一致,应用采用Windows身份验证
- 项目包引用:
<ItemGroup> <PackageReference Include="ClosedXML" Version="0.104.1" /> <PackageReference Include="log4net" Version="2.0.17" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="8.0.10" /> <PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="8.0.0" /> <PackageReference Include="MudBlazor" Version="7.15.0" /> <PackageReference Include="System.DirectoryServices.AccountManagement" Version="8.0.1" /> </ItemGroup>
排查与解决方法
1. 显式添加Microsoft.Extensions.Localization引用
MudBlazor依赖该组件,但依赖链解析可能存在不确定性。直接在项目中添加显式引用,确保发布时DLL被强制复制到输出目录:
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0" />
2. 调整IIS应用程序池配置
随机异常常与应用池回收或加载策略相关:
- 检查应用程序池的加载用户配置文件选项,设置为
True(IIS管理器 -> 应用程序池 -> 高级设置),避免权限不足导致的DLL读取失败 - 调整回收设置:禁用不必要的定时回收,或延长回收间隔,减少因回收导致的DLL重新加载问题
3. 验证DLL完整性与权限
- 重新发布前,清理生产环境部署目录的旧文件,避免新旧文件冲突
- 确认
Microsoft.Extensions.Localization.dll的权限,确保应用程序池标识(如ApplicationPoolIdentity)拥有该文件的读取和执行权限
4. 启用程序集绑定日志排查细节
使用程序集绑定日志查看器定位加载失败的具体原因:
- 以管理员身份打开命令提示符,执行
fuslogvw.exe - 在工具中设置日志目录,启用“记录所有绑定失败”,当异常再次出现时,查看是否存在版本冲突或绑定路径错误
5. 优化MudBlazor本地化配置
异常发生在MudBlazor本地化拦截器初始化阶段:
- 确保
Program.cs中已正确注册本地化服务:builder.Services.AddLocalization(); - 若无需本地化功能,可显式禁用:
builder.Services.AddMudServices(config => { config.LocalizationEnabled = false; });
6. 更新.NET 8运行时
确保生产服务器安装了最新的.NET 8运行时补丁,修复可能存在的程序集加载bug。
内容的提问来源于stack exchange,提问作者user28700992
相关产品推荐
相关产品推荐

