在 Blazor 中向 App.razor 路由器添加一个附加程序集会导致 _Host.cshtml 抛出 'Object reference not set to an instance of an object'

Adding an additional assembly to App.razor router in Blazor causes _Host.cshtml to throw 'Object reference not set to an instance of an object'

我有一个包含 Razor 组件和页面的 Razor Class 库 (RCL)。此 RCL 有一个名为“Pages”的文件夹,其中包含一个 Index.razor 页面和一个名为 Details.razor 的页面。我已将 RCL 添加到 Blazor Server 项目,引用它,并试图让宿主项目中的路由器知道在哪里可以找到 Details.razor 页面(宿主项目已经包含一个索引页面,不会使用RCL 版本)。这是我的路由器代码 App.razor:

<Router AppAssembly="@typeof(App).Assembly"
    AdditionalAssemblies="new[] { 
        typeof(MyRcl.Pages.Details).Assembly
    }">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

构建项目从 _Host.cshtml 文件的最后一行抛出以下异常:

@page "/"
@namespace MyProject.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = "_Layout";
}

<component type="typeof(App)" render-mode="ServerPrerendered" />

System.NullReferenceException: 'Object reference not set to an instance of an object.'

调用堆栈:

>   
MyProject.dll!MyProject.Pages.Pages__Host.ExecuteAsync() Line 8 C#
    Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAdapter.ExecuteAsync()  Unknown
    Microsoft.AspNetCore.Mvc.Razor.dll!Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(Microsoft.AspNetCore.Mvc.Razor.IRazorPage page, Microsoft.AspNetCore.Mvc.Rendering.ViewContext context) Unknown
    Microsoft.AspNetCore.Mvc.Razor.dll!Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(Microsoft.AspNetCore.Mvc.Razor.IRazorPage page, Microsoft.AspNetCore.Mvc.Rendering.ViewContext context, bool invokeViewStarts)  Unknown
    Microsoft.AspNetCore.Mvc.Razor.dll!Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(Microsoft.AspNetCore.Mvc.Rendering.ViewContext context) Unknown
    Microsoft.AspNetCore.Mvc.ViewFeatures.dll!Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext, string contentType, int? statusCode)  Unknown
    Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageResultExecutor.ExecuteAsync(Microsoft.AspNetCore.Mvc.RazorPages.PageContext pageContext, Microsoft.AspNetCore.Mvc.RazorPages.PageResult result)  Unknown
    Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.PageResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context)   Unknown
    Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultAsync(Microsoft.AspNetCore.Mvc.IActionResult result)  Unknown
    Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeResultAsync(Microsoft.AspNetCore.Mvc.IActionResult result)   Unknown
    Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<Microsoft.AspNetCore.Mvc.Filters.IResultFilter, Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter>(ref Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.State next, ref Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Scope scope, ref object state, ref bool isCompleted)  Unknown
    Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResultFilterAsync<Microsoft.AspNetCore.Mvc.Filters.IResultFilter, Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter>()    Unknown
    Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<Microsoft.AspNetCore.Mvc.Filters.IResultFilter, Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter>(ref Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.State next, ref Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Scope scope, ref object state, ref bool isCompleted)  Unknown
    Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters() Unknown
    Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.State next, ref Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Scope scope, ref object state, ref bool isCompleted) Unknown
    Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResourceFilter()    Unknown
    Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.State next, ref Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Scope scope, ref object state, ref bool isCompleted) Unknown
    Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()   Unknown
    Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeAsync() Unknown
    Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageRequestDelegateFactory.CreateRequestDelegate.AnonymousMethod__0(Microsoft.AspNetCore.Http.HttpContext context)   Unknown
    Microsoft.AspNetCore.Routing.dll!Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext httpContext)  Unknown
    Microsoft.AspNetCore.Routing.dll!Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext httpContext)   Unknown
    Microsoft.AspNetCore.StaticFiles.dll!Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context)    Unknown
    Microsoft.AspNetCore.HttpsPolicy.dll!Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context)  Unknown
    Microsoft.AspNetCore.HttpsPolicy.dll!Microsoft.AspNetCore.HttpsPolicy.HstsMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context)  Unknown
    Microsoft.AspNetCore.Diagnostics.dll!Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context)    Unknown
    Microsoft.AspNetCore.Diagnostics.dll!Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context)    Unknown
    Microsoft.AspNetCore.HostFiltering.dll!Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context) Unknown
    Microsoft.WebTools.BrowserLink.Net.dll!Microsoft.WebTools.BrowserLink.Net.BrowserLinkMiddleware.ExecuteWithFilterAsync(Microsoft.WebTools.BrowserLink.Net.IHttpSocketAdapter injectScriptSocket, string requestId, Microsoft.AspNetCore.Http.HttpContext httpContext)   Unknown
    Microsoft.WebTools.BrowserLink.Net.dll!Microsoft.WebTools.BrowserLink.Net.BrowserLinkMiddleware.InvokeAsync(Microsoft.AspNetCore.Http.HttpContext context)  Unknown
    Microsoft.AspNetCore.Watch.BrowserRefresh.dll!Microsoft.AspNetCore.Watch.BrowserRefresh.BrowserRefreshMiddleware.InvokeAsync(Microsoft.AspNetCore.Http.HttpContext context) Unknown
    Microsoft.AspNetCore.Http.Abstractions.dll!Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context)  Unknown
    Microsoft.AspNetCore.Hosting.dll!Microsoft.AspNetCore.Hosting.HostingApplication.ProcessRequestAsync(Microsoft.AspNetCore.Hosting.HostingApplication.Context context)   Unknown
    Microsoft.AspNetCore.Server.Kestrel.Core.dll!Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests<Microsoft.AspNetCore.Hosting.HostingApplication.Context>(Microsoft.AspNetCore.Hosting.Server.IHttpApplication<Microsoft.AspNetCore.Hosting.HostingApplication.Context> application)    Unknown
    Microsoft.AspNetCore.Server.Kestrel.Core.dll!Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync<Microsoft.AspNetCore.Hosting.HostingApplication.Context>(Microsoft.AspNetCore.Hosting.Server.IHttpApplication<Microsoft.AspNetCore.Hosting.HostingApplication.Context> application)   Unknown
    Microsoft.AspNetCore.Server.Kestrel.Core.dll!Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Stream<Microsoft.AspNetCore.Hosting.HostingApplication.Context>.Execute() Unknown
    System.Private.CoreLib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()  Unknown
    System.Private.CoreLib.dll!System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart() Unknown
    System.Private.CoreLib.dll!System.Threading.Thread.StartCallback()  Unknown

如果我从路由器配置中删除“AdditionalAssemblies”语句,应用程序构建并运行正常,所以我很确定它触发了错误但不确定是什么导致了它(我已经仔细检查了语法并将它与我使用 RCL 中的 Razor 页面的其他应用程序进行比较,代码似乎是正确的)。任何有助于进一步澄清潜在问题的帮助或想法都将受到赞赏。

找到问题 - 将 post 放在这里以防其他人遇到难以识别的相同问题。这是一个 .NET 6 问题的变体,描述为 here and here which is slotted for consideration in .NET 7. In my case the issue was the duplicate Index.razor files in the host project and RCL (not the Details.razor file I was trying to consume from the RCL). The duplicate files should not be an issue per MS documentation,因为托管应用程序中的文件应该优先。在我尝试修改 App.razor 以使用 RCL 中的详细信息页面之前,情况确实如此,此时发生了异常(即使我只引用了未重复的详细信息页面并且 not 路由器代码中的索引页)。我可以通过删除 RCL 中未使用的索引页来解决异常(但这不是永久解决方案,因为它在其他项目中使用)。我现在的解决方法是覆盖两个 RCL 页面并从 App.razor.

中删除 AdditionalAssemblies 语句