#iis #blazor
Вопрос:
Я пытаюсь развернуть свое приложение для веб-сборки Blazor (.NET 5.0) на сервере IIS. Когда я загружаю страницу, я получаю сообщение об ошибке HTTP 404. С этим также есть API, для которого я использую Swagger. Я могу загрузить Swagger, а также запросить API через Postman, просто пользовательский интерфейс Blazor не загружается. Пожалуйста, по каким причинам это может быть вызвано?
Я установил пакет хостинга среды выполнения .NET Core на сервере. В консоли не появляется никаких ошибок index.html присутствует в папке wwwroot
Если я опубликую приложение Blazor самостоятельно, то страница загрузится (с ошибками, так как API не был загружен). Когда я публикую из приложения Web API, API работает, но Blazor-нет.
Применение Блейзора
.NET 5.0
Web.config —
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".AppName.Server.dll" stdoutLogEnabled="false" stdoutLogFile=".logsstdout" hostingModel="inprocess" />
</system.webServer>
Программа.cs —
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.RootComponents.Add<App>("app");
builder.Services.AddBlazoredLocalStorage();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider, ApiAuthenticationStateProvider>();
builder.Services.AddHttpClient<IAuthService, AuthService>();
builder.Services.AddScoped<DialogService>();
builder.Services.AddScoped<NotificationService>();
builder.Services.AddScoped<TooltipService>();
builder.Services.AddScoped<ContextMenuService>();
builder.Services.AddScoped<ClipboardService>();
await builder.Build().RunAsync();
}
Веб-API —
.NET 5.0
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.
public void ConfigureServices(IServiceCollection services)
{
services.AddServerSideBlazor();
services.AddMvc().AddNewtonsoftJson();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "AppTitle API", Version = "v1" });
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).EnableDetailedErrors());
services.AddDefaultIdentity<IdentityUser>(options => options.Lockout.AllowedForNewUsers = false)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtAudience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSecurityKey"]))
};
services.AddSingleton(tokenValidationParameters);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = tokenValidationParameters;
});
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("https://localhost:44326",
"https://localhost:44345")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseResponseCompression();
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), @"upload")),
RequestPath = new PathString("/upload")
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("v1/swagger.json", "AppTitle API"));
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}
Обновить
Сбой трассировки запросов в IIS
Единственная ошибка, возникающая в FRT, — это —
- -УВЕДОМЛЕНИЕ_MODULE_START
Имя модуля AspNetCoreModuleV2
Обработчик запросов на ВЫПОЛНЕНИЕ уведомлений
fIsPostNotification ложно
750 мс
Предупреждение 103. -MODULE_SET_RESPONSE_ERROR_STATUS
Имя модуля AspNetCoreModuleV2
Обработчик запросов на ВЫПОЛНЕНИЕ уведомлений
HttpСтатус 404
HttpReason Не найден
HttpSubStatus 0
Код ошибки: Операция успешно завершена. (0x0)
ConfigExceptionInfo
Комментарии:
1. WebAssemblyHostBuilder-это не «сервер Blazor». Вопрос противоречит сам себе.
2. Постарайтесь четко определить, какие у вас есть проекты, как вы их установили, какие версии и т.д.
3. Вы развернули приложение во вложенной папке? В этом случае вам необходимо обновить базовую ссылку в вашем index.html
4. @HenkHolterman Спасибо, неправильное использование формулировок. Я расширил в оригинальном посте.
5. @NicolaBiada там нет подкаталога
Ответ №1:
Одной из возможных проблем, связанных с 404 развертыванием Blazor WASM в IIS, является отсутствие модуля перезаписи URL-адресов.
Этот модуль необходим для того, чтобы использовать систему маршрутизации Blazor.
Пожалуйста, перейдите по следующей ссылке для получения дополнительной информации: https://docs.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/webassembly?view=aspnetcore-5.0#rewrite-urls-for-correct-routing-1
Файл web.config для развернутого приложения WASM должен быть следующим:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".blat" />
<remove fileExtension=".dat" />
<remove fileExtension=".dll" />
<remove fileExtension=".json" />
<remove fileExtension=".wasm" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<mimeMap fileExtension=".blat" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dll" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dat" mimeType="application/octet-stream" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".wasm" mimeType="application/wasm" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
</staticContent>
<httpCompression>
<dynamicTypes>
<add mimeType="application/octet-stream" enabled="true" />
<add mimeType="application/wasm" enabled="true" />
</dynamicTypes>
</httpCompression>
<rewrite>
<rules>
<rule name="Serve subdir">
<match url=".*" />
<action type="Rewrite" url="wwwroot{R:0}" />
</rule>
<rule name="SPA fallback routing" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="wwwroot" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Комментарии:
1. Модуль перезаписи URL-адреса не установлен. Я заметил, хотя, когда я развернул только Blazor, в файле web.config были некоторые правила перезаписи URL-адресов. Когда я развертывался с сервера, в файле Web.config не было правил перезаписи URL-адресов.
2. Проверьте мой ответ, я добавил пример web.config для приложения WASM.
3. Все равно не везет. Я добавил свой текущий web.config в сообщение. Я добавил в это твою долю. Добавление вышеуказанного бита также нарушает работу API.