Blazor WASM постоянно обновляет

#asp.net-core #identityserver4 #blazor #blazor-webassembly

#asp.net-ядро #identityserver4 #blazor #blazor-webassembly

Вопрос:

У меня есть проект blazor WASM, который отлично работает при разработке и локальном производстве (на моем компьютере), но не на производственном сервере Linux. Когда я публикую проект на рабочем сервере (Ubuntu 20.04), проект продолжает отправлять запросы (только на клиенте, а не на сервере)
Что это может быть? Я не устанавливал SSL-сертификат, поэтому все запросы являются http, а не https.

https://gfycat.com/reliablefarawaycurlew

Program.cs в клиентском проекте

 public class Program
{
    public static async Task Main(string[] args)
    {
        var builder = WebAssemblyHostBuilder.CreateDefault(args);
        builder.RootComponents.Add<App>("app");

        builder.Services.AddHttpClient("BlazorAppManagerWeb.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
            .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
        builder.Services.AddSingleton(new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
        ConfiguteServices(builder.Services);

        var host = builder.Build();

        var js = host.Services.GetRequiredService<IJSRuntime>();
        //var culture = await js.InvokeAsync<string>("getFromLocalStorage", "culture");
        string culture = null;

        CultureInfo selectedCulture;

        if (culture == null)
        {
            selectedCulture = new CultureInfo("he-IL");
        }
        else
        {
            selectedCulture = new CultureInfo(culture);
        }

        CultureInfo.DefaultThreadCurrentCulture = selectedCulture;
        CultureInfo.DefaultThreadCurrentUICulture = selectedCulture;

        await host.RunAsync();
    }

    public static void ConfiguteServices(IServiceCollection services)
    {
        services.AddLocalization();
        services.AddScoped<IHttpService, HttpService>();
        services.AddScoped<Repository.IEntityRepository, Repository.EntityRepository>();
        services.AddScoped<IMyVehicleRepository, MyVehicleRepository>();
        services.AddScoped<IMyVehicleCommentRepository, MyVehicleCommentRepository>();
        services.AddScoped<IVehicleTypeRepository, VehicleTypeRepository>();
        services.AddScoped<IVehicleManufacturerRepository, VehicleManufacturerRepository>();
        services.AddScoped<IVehicleModelRepository, VehicleModelRepository>();
        services.AddScoped<IMyVehicleStatusRepository, MyVehicleStatusRepository>();
        services.AddScoped<IDocumentRepository, DocumentRepository>();
        services.AddScoped<IItemRepository, ItemRepository>();
        services.AddScoped<IMissionRepository, MissionRepository>();
        services.AddScoped<ICustomerVehicleRepository, CustomerVehicleRepository>();
        services.AddScoped<ICustomerVehicleStatusRepository, CustomerVehicleStatusRepository>();
        services.AddScoped<IMissionCardRepository, MissionCardRepository>();
        services.AddScoped<IBankRepository, BankRepository>();
        services.AddScoped<IDepositRepository, DepositRepository>();
        services.AddScoped<IGeneralRepository, GeneralRepository>();
        services.AddScoped<IEntityCommentRepository, EntityCommentRepository>();
        services.AddScoped<IEntityToDoRepository, EntityToDoRepository>();
        services.AddScoped<ICalendarRepository, CalendarRepository>();
        services.AddScoped<IReportsRepository, ReportsRepository>();
        services.AddScoped<Repository.InSControl.IEntityRepository, Repository.InSControl.EntityRepository>();
        services.AddScoped<IDisplayMessage, DisplayMessage>();
        services.AddFileReaderService(options => options.InitializeOnFirstCall = true);

        /* LOCALIZATION MANUALLY SET TO HEBREW
        var culture = new CultureInfo("he-IL");
        CultureInfo.DefaultThreadCurrentCulture = culture;
        CultureInfo.DefaultThreadCurrentUICulture = culture;*/

        // Supply HttpClient instances that include access tokens when making requests to the server project
        services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("BlazorAppManagerWeb.ServerAPI"));

        services.AddApiAuthorization();
    }
}
  

Program.cs на сервере

 public class Program
{
    public static void Main(string[] args)
    {
        var webHost = CreateHostBuilder(args).Build();

        using(var scope = webHost.Services.CreateScope())
        {
            var services = scope.ServiceProvider;
            var context = services.GetService<ApplicationDbContext>();
            context.Database.Migrate();

            var context2 = services.GetService<ControlDbContext>();
            context2.Database.Migrate();
        }

        webHost.Run();
    }

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

Startup.cs в клиентском проекте

 public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>();

        services.AddDbContext<ControlDbContext>(options =>
        {
            options.UseSqlServer(
                Configuration.GetConnectionString("ControlConnection"));
        });

        services.AddDefaultIdentity<ApplicationUser>(options => {
            options.SignIn.RequireConfirmedAccount = false;
            options.Password.RequireDigit = false;
            options.Password.RequireLowercase = false;
            options.Password.RequireUppercase = false;
            options.Password.RequireNonAlphanumeric = false;
            })
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddTransient<IEmailSender, EmailSender>();

        services.AddIdentityServer()
            .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

        services.ConfigureExternalCookie(options => {
            options.Cookie.IsEssential = true;
            options.Cookie.SameSite = SameSiteMode.Unspecified; //SameSiteMode.Unspecified in .NET Core 3.1
            options.ExpireTimeSpan = TimeSpan.FromDays(365);
        });

        services.ConfigureApplicationCookie(options => {
            options.Cookie.IsEssential = true;
            options.Cookie.SameSite = SameSiteMode.Unspecified; //SameSiteMode.Unspecified in .NET Core 3.1
            options.ExpireTimeSpan = TimeSpan.FromDays(365);
        });

        services.AddAuthentication()
            .AddIdentityServerJwt();

        services.AddAutoMapper(typeof(Startup));

        services.AddScoped<IFileStorageService, InAppStorageService>();
        services.AddHttpContextAccessor();
        services.AddTransient<IUserRepository, UserRepository>();
        services.AddTransient<IEntityRepository, EntityRepository>();

        services.AddMvc().AddNewtonsoftJson(options=> options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddTransient<CustomerVehiclesController, CustomerVehiclesController>();
        CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("he-IL");
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
            app.UseWebAssemblyDebugging();
        }
        else
        {
            app.UseExceptionHandler("/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.UseHttpsRedirection();
        app.UseBlazorFrameworkFiles();
        app.UseStaticFiles();

        app.UseRouting();

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

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("index.html");
        });
    }
}
  

Комментарии:

1. «продолжать отправлять запросы (только на клиенте, а не на сервере)» не очень понятно.

2. @HenkHolterman Решение Blazor WASM создано с использованием 3 проектов — клиентского, серверного и общего, страницы выполняются на клиенте, но поскольку я использую аутентификацию с использованием отдельных учетных записей пользователей, оно сгенерировало систему аутентификации в серверном проекте. когда я нахожусь на странице входа в систему, которая хранится в серверном проекте, у меня нет никаких проблем, но когда я нахожусь на страницах, связанных с клиентским проектом I, он продолжает отправлять запрос, как в gif, который я прикрепил к вопросу

3. Скорее всего: включить WebSockets на сервере prod.