当 运行 IIS 上的发布版本时,Blazor WebAssembly InvalidCastException

Blazor WebAssembly InvalidCastException when running Published version on IIS

我有一个 Blazor WebAssembly 应用程序,它在调试时运行良好,但在 IIS 上 运行 时抛出异常(已发布):

blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Specified cast is not valid.
System.InvalidCastException: Specified cast is not valid.
   at Microsoft.AspNetCore.Components.Reflection.MemberAssignment.GetPropertiesIncludingInherited(Type , BindingFlags )+MoveNext()
   at Microsoft.AspNetCore.Components.ComponentFactory.CreateInitializer(Type )
   at Microsoft.AspNetCore.Components.ComponentFactory.PerformPropertyInjection(IServiceProvider , IComponent )
   at Microsoft.AspNetCore.Components.ComponentFactory.InstantiateComponent(IServiceProvider , Type )
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateComponent(Type )
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateChildComponentOnFrame(RenderTreeFrame& , Int32 )
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& , Int32 )
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& , Int32 )
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& , Int32 )
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& , Int32 , Int32 , Int32 , Int32 )
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer , RenderBatchBuilder , Int32 , ArrayRange`1 , ArrayRange`1 )
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder , RenderFragment , Exception& )
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry )
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

这个错误非常无用 i.m.o,因为我找不到确切的原因,而不是 invalid cast exception

因为无法在已发布的 IIS 站点上进行调试,所以我将 Console.WriteLine 添加到 Program.cs 和第一个 Index.razor。但是,错误发生在 Index.razor 被渲染之前。在 await builder.Build().RunAsync(); 调用之前我的 Program.main 中的所有代码也能正常工作。

所以我想这与我的App.razorMainLayout.razor有关。现在 MainLayout.razor 位于具有命名空间 Libs.Blazor.Components.Shared.

的 Razor Class 库中

Program.cs

  /// <summary>
  /// Program entry
  /// </summary>
  public class Program {

    /// <summary>
    /// Entry point of application
    /// </summary>
    /// <param name="args">Arguments to pass</param>
    /// <returns>Task with a result</returns>
    public static async Task Main (String[] args) {
      var builder = WebAssemblyHostBuilder.CreateDefault(args);
      builder.RootComponents.Add<App>("#app");
      builder.RootComponents.Add<HeadOutlet>("head::after");

      HttpClient http = new HttpClient() {
        BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
      };

      IHostEnvironment hostEnvironment = new HostEnvironment() {
        ApplicationName = builder.HostEnvironment.Environment,
        EnvironmentName = builder.HostEnvironment.Environment,
        ContentRootPath = builder.HostEnvironment.Environment
      };

      builder.Services.AddScoped(sp => http);
      builder.Services.AddScoped(sp => hostEnvironment);

      using HttpResponseMessage response = await http.GetAsync("appsettings.json"); //Load the appsettings
      using Stream stream = await response.Content.ReadAsStreamAsync();

      builder.Configuration.AddJsonStream(stream);
      await builder.Build().RunAsync();
    } // Main

    /// <summary>
    /// HotEnvironment filled by WebAssembly
    /// </summary>
    internal class HostEnvironment :IHostEnvironment {
      private String m_EnvironmentName;
      private String m_ApplicationName;
      private String m_ContentRootPath;
      private IFileProvider m_ContentRootFileProvider;

      /// <summary>
      /// EnvironmentName
      /// </summary>
      public String EnvironmentName { [DebuggerStepThrough()] get { return m_EnvironmentName; } set { m_EnvironmentName = value; } }

      /// <summary>
      /// ApplicationName
      /// </summary>
      public String ApplicationName { [DebuggerStepThrough()] get { return m_ApplicationName; } set { m_ApplicationName = value; } }

      /// <summary>
      /// ContentRootPath
      /// </summary>
      public String ContentRootPath { [DebuggerStepThrough()] get { return m_ContentRootPath; } set { m_ContentRootPath = value; } }

      /// <summary>
      /// FileProvider
      /// </summary>
      public IFileProvider ContentRootFileProvider { [DebuggerStepThrough()] get { return m_ContentRootFileProvider; } set { m_ContentRootFileProvider = value; } }
    } // Class HostEnvironment
  } // Class Program

App.razor

<Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Libs.Blazor.Components.Shared.MainLayout).Assembly }">
  <Found Context="routeData">
    <RouteView RouteData="@routeData" DefaultLayout="@typeof(Libs.Blazor.Components.Shared.MainLayout)" />
  </Found>
  <NotFound>
    <LayoutView Layout="@typeof(Libs.Blazor.Components.Shared.MainLayout)">
      <p>Sorry, there's nothing at this address.</p>
    </LayoutView>
  </NotFound>
</Router>

Libs.Blazor.Components.Shared.MainLayout

@namespace Libs.Blazor.Components.Shared
@inherits LayoutComponentBase

<body id="LibsBody" class="LibsBody" style="cursor:default;">
  @Body
  <div id="LibsHidden"></div>
</body>

所以我很困惑为什么我在 IIS 上得到这个 Invalid Cast Exception 运行 应用程序,但在 VS 中调试它时却没有。

我遇到了同样的问题。对我有用的解决步骤是在托管 IIS 的 Windows 服务器上安装 .net 6 托管包。然后我重新启动了 IIS 服务器并从 VS2022 重新发布了我的应用程序。现在一切正常。希望这有帮助。

我偶然通过查看发布配置文件解决了这个问题。目标运行时以某种方式设置为 Portable,而不是所需的 browser-wasm.