Im trying to deploy my Blazor WebAssembly application (.NET 5.0) to an IIS server. When I load the page I get a HTTP Error 404. With this there is also an API which I use Swagger for. I can load Swagger and also query the API via Postman, its just the Blazor UI doesn't load. WHat reasons could cause this please?
I have installed the .NET Core Runtime Hosting Bundle on the server. There are no errors appearing in the console index.html is present in wwwroot folder
If I publish the Blazor application on its own, then the page loads (with errors as the API has not been uploaded). When I publish from the Web API application then the API works but the Blazor doesn't.
Blazor Application
.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=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
Program.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();
}
Web 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();
});
}
}
UPDATE
Failed Request Trace in IIS
The only error produced in FRT is -
- -NOTIFY_MODULE_START
ModuleName AspNetCoreModuleV2
Notification EXECUTE_REQUEST_HANDLER
fIsPostNotification false
750 ms
Warning 103. -MODULE_SET_RESPONSE_ERROR_STATUS
ModuleName AspNetCoreModuleV2
Notification EXECUTE_REQUEST_HANDLER
HttpStatus 404
HttpReason Not Found
HttpSubStatus 0
ErrorCode The operation completed successfully. (0x0)
ConfigExceptionInfo