2

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 -

  1. -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

8
  • WebAssemblyHostBuilder is not "Blazor Server". The question is contradicting itself. Commented Aug 17, 2021 at 9:44
  • Try to be clear about which Projects you have, how you installed them, what version(s) etc. Commented Aug 17, 2021 at 9:46
  • Do you have deployed the application in a subfolder? In that case you need to update the base href in your index.html Commented Aug 17, 2021 at 12:00
  • @HenkHolterman Thanks, misuse of wording. I have expanded in the original post. Commented Aug 17, 2021 at 12:42
  • @NicolaBiada theres no sub directory Commented Aug 17, 2021 at 12:42

1 Answer 1

0

One of the possible issues about a 404 deploying a Blazor WASM on IIS is the lack of the URL Rewrite Module.
This module is essential in order to use the routing system of Blazor.

Please refer to the following link for more information: https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/webassembly?view=aspnetcore-5.0#rewrite-urls-for-correct-routing-1

The web.config file for the deployed WASM application should be like the following:

<?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>
Sign up to request clarification or add additional context in comments.

3 Comments

The URL Rewrite module is isntalled. I did notice though when I deployed just the Blazor, the web.config file had some URL rewrite rules. When I deployed from the server, the Web.config had no URL rewrite rules.
Check my answer, I've added a web.config example for a WASM application.
Still no luck. I have added my current web.config to the post. I added your bit in to it. Adding the above bit breaks the API as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.