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

ASP.NET Core(.NET5)集成Blazor时blazor.server.js 404错误求助

ASP.NET Core (.NET 5) 集成Blazor时的404错误求助

我有一个ASP.NET Core(.NET 5)应用,想要集成Blazor,已完成以下配置:

  • 在Startup.cs的ConfigureServices方法中,通过ConfigureBlazorComponents方法执行了services.AddServerSideBlazor();
  • 在Configure方法的端点配置里添加了endpoints.MapRazorPages();和endpoints.MapBlazorHub();
  • 配置了app.UseStaticFiles(),同时在Program.cs中设置了webBuilder.UseStaticWebAssets();
  • 在_Layout.cshtml的<head>标签内添加了<base href="~/"/>以及<script src="_framework/blazor.server.js"></script>标签

但目前遇到的问题:

  • 编译完成后,未生成_framework文件夹
  • 运行应用时,持续出现https://localhost:{port}/_framework/blazor.server.js net::ERR_ABORTED 404错误
  • 访问https://localhost:{port}/_blazor时返回“Connection ID required”,但浏览器DevTools的网络面板中看不到negotiate请求

我已参考多篇教程及GitHub示例尝试解决,但均未成功,希望获得帮助。以下是完整的Startup.cs和Program.cs配置:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    CustomConfigureServices(services, Configuration);
    services.AddSingleton<MyDataProtection>();


    services.AddDistributedMemoryCache();


    services.AddMvc(options => {
        options.Filters.Add(new CustomActionFilter());
    });
    services.Configure<CookiePolicyOptions>(options => {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        //options.CheckConsentNeeded = context => true;

        options.CheckConsentNeeded = context => false;

        options.MinimumSameSitePolicy = SameSiteMode.Unspecified;

        // Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1

        options.HandleSameSiteCookieCompatibility();

    });
    services.Configure<FormOptions>(options => {
        options.ValueCountLimit = int.MaxValue;
    });

    services.AddOptions();

    services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme, options =>

            {

                options.AccessDeniedPath = new PathString("/Account/AccessDenied");

            });


            services.AddScoped<IClaimsTransformation, AddRolesClaimsTransformation>();


            string _pluginsPath = $"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}{Path.DirectorySeparatorChar}Plugins";


            string[] _pluginsDlls = Directory.GetFiles(_pluginsPath).Where(s => s.EndsWith(".plugin.dll", StringComparison.CurrentCultureIgnoreCase)).ToArray();


            List<Assembly> _pluginsAssemblies = new();


            foreach (string _dll in _pluginsDlls)

            {

                Assembly _pluginAssembly = Assembly.LoadFrom(_dll);


                if (_pluginAssembly.GetTypes().Where(t => t.IsAssignableTo(typeof(IPlugin))).Any())

                {

                    _pluginsAssemblies.Add(_pluginAssembly);

                }

            }


            foreach (Assembly item in _pluginsAssemblies)

            {

                services.AddControllersWithViews()

                    .AddApplicationPart(item)

                    .AddRazorRuntimeCompilation();



                services.Configure<MvcRazorRuntimeCompilationOptions>(options =>

                { options.FileProviders.Add(new EmbeddedFileProvider(item)); });

            }


            services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)

                    .AddMicrosoftIdentityWebApp(options =>

                        {

                            Configuration.Bind("AzureAd", options);

                            options.GetClaimsFromUserInfoEndpoint = true;

                            options.Events ??= new OpenIdConnectEvents();

                            //see: https://github.com/openiddict/openiddict-core/issues/334 https://xtremeownage.com/2021/11/10/asp-net-core-links-dont-work-from-office-word-document-to-sso-site/

                            options.Events.OnRemoteFailure += OnRemoteFailureFuncAsync;

                            options.Events.OnTokenValidated += OnTokenValidatedFuncAsync;

                        }

                    )

                    .EnableTokenAcquisitionToCallDownstreamApi(

                        Configuration.GetSection("WebApplications:WebApplicationsScopes").Get<string>().Split(" ", System.StringSplitOptions.RemoveEmptyEntries)

                        )

                    .AddInMemoryTokenCaches();


            // Add APIs

            services.AddWebApplicationsService(Configuration);


            services.AddControllers().AddNewtonsoftJson(jsonOptions =>

            {

                jsonOptions.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();

            });


            // Add the Kendo UI services to the services container.

            services.AddKendo();


            //Configure Session

            services.AddSession(options =>

            {

                options.IdleTimeout = TimeSpan.FromMinutes(40); //TODO get time for session 

                options.Cookie.HttpOnly = true;

                options.Cookie.IsEssential = true;

            });

            services.AddControllersWithViews(options =>

            {

                var policy = new AuthorizationPolicyBuilder()

                    .RequireAuthenticatedUser()

                    .Build();

                options.Filters.Add(new AuthorizeFilter(policy));

            }).AddMicrosoftIdentityUI();


            services.AddRazorPages();


            services.AddResponseCompression(options =>

            {

                options.EnableForHttps = true;

            });


            ConfigureBlazorComponents(services, _pluginsAssemblies);
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
        {
            app.UseSession();
            if (!env.IsProduction())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }


            app.UseCatchSecurityExceptionsMiddleware();


            app.UseHttpsRedirection();
            var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
            app.UseStaticFiles(new StaticFileOptions
            {
                OnPrepareResponse = ctx =>
                {
                    ctx.Context.Response.Headers.Append(
                         "Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
                }
            });
            app.UseCookiePolicy();
            app.UseResponseCompression();
            app.UseRouting();


            app.UseAuthentication();
            app.UseAuthorization();


            IDictionary<string, string> _appSettings = ConfigurationHelper.AppSettings;
            string defaultController;
            _appSettings.TryGetValue("DefaultController", out defaultController);
            if (string.IsNullOrEmpty(defaultController))
            {
                defaultController = ApplicationConfig.DefaultController;
            }


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "landingpage",
                    pattern: "LandingPage",
                    defaults: new { controller = "LandingPage", action = "Index" });


                endpoints.MapControllerRoute(
                    name: "menuPlugin",
                    pattern: "Menu{ControllerPlugin}.{ActionPlugin}",
                    defaults: new { controller = "Home", action = "Index", ControllerPlugin = ApplicationConfig.DefaultController, ActionPlugin = ApplicationConfig.DefaultAction });


                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller}/{action}",
                    defaults: new { controller = "Home", action = "Index" });


                endpoints.MapControllerRoute(
                   name: "showAnnotation",
                   pattern: "ShowAnnotation",
                   defaults: new { controller = "Home", action = "ShowAnnotation" });


                endpoints.MapControllerRoute(
                   name: "comesFromPortal",
                   pattern: "ComesFromPortal",
                   defaults: new { controller = "Home", action = "ComesFromPortal" });


                endpoints.MapRazorPages();
                endpoints.MapBlazorHub();


                lifetime.ApplicationStopped.Register(CloseAndFlushLog); //register callback to flush pending log events before shutdown


            });
}

注:ConfigureBlazorComponents(services, _pluginsAssemblies)方法中执行了services.AddServerSideBlazor();

Program.cs

public static void Main(string[] args)
{
    SerilogSetup.Setup();
    CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .UseSerilog()
        .ConfigureWebHostDefaults(webBuilder =>
        {
             webBuilder.UseStaticWebAssets();
             webBuilder.UseStartup<Startup>();
        });

内容的提问来源于stack exchange,提问作者Nahuel Leiva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:55:07