2

I have added a webapi project to my solution with a controller to do an HttpGet. The Blazor server project can access it fine locally and deployed. I can make a postman call to the service locally, but the deployed version is giving me the Blazor connection failed message from my _Host file. How would I configure webapi access externally without Blazor interfering?

I think it may be a routing issue of some kind that I need to work out. I am using .NET5 and my webapi startup has this:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseSwagger();
        app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "myapp.WebApi v1"));
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

WebApi Program.cs:

namespace myapp.WebApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

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

Blazor Program.cs:

namespace myapp.UI
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

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

My blazor project Startup:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UsePathBase("/myapp");

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
        //TelemetryDebugWriter.IsTracingDisabled = true;
    }
    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();
    }

    // SD2: app.UseSession();

    app.UseHttpsRedirection();
    app.UseStaticFiles();

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

    // SD2: app.UseMvc();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapBlazorHub();

        // prior fallback setting
        // endpoints.MapFallbackToPage("/_Host");
        
        // 1/4/22 https://stackoverflow.com/questions/61268117/how-to-map-fallback-in-asp-net-core-web-api-so-that-blazor-wasm-app-only-interc
        endpoints.MapFallbackToPage("{*path:regex(^(?!api).*$)}", "/_Host"); // don't match paths beginning with api
    });

}

I am investigating ways to route .../api/... calls to the webapi project and everything else to the blazor project.

In VS, my call that works is https://localhost:44368/api/controller/GetFoos/Year=2020

My deployed call (tried several variations) https://serverName/appName/api/controller/GetFoos/Year=2020

Fails in Blazor. I want Blazor to ignore and have the WebApi handle it.

Steve Greene
  • 11,559
  • 1
  • 29
  • 48

2 Answers2

1

This is just some code to show how you run API controllers and Blazor on the same site.

You normally add controllers to a Blazor Server project like this:

Add the services

services.AddControllers();

Or if the controllers are in another project/assembly

services.AddControllers().PartManager.ApplicationParts.Add(new AssemblyPart(typeof(Blazr.Database.Controllers.WeatherForecastController).Assembly));

Then set up the middleware pipeline like this:

   app.UseEndpoints(endpoints =>
   {
      endpoints.MapControllers();
      endpoints.MapBlazorHub();
      endpoints.MapRazorPages();
      endpoints.MapFallbackToPage("/_Host");
   });

_Host.cshtml being the Blazor Server SPA launch file.

endpoints.MapControllers(); intercepts and fulfills all requests for the controllers. The Blazor App startup page is the final fallback.

MrC aka Shaun Curtis
  • 7,554
  • 1
  • 7
  • 21
  • Hey, I decided to scrap the separate project and just add the api controller to my existing Blazor app. Now I have a security issue I have added a separate question for here: https://stackoverflow.com/questions/70669528/blazor-server-with-web-api-controller-authenticate-issue – Steve Greene Jan 11 '22 at 15:46
0

You can also try this (from brief testing it seems working). Try to map fallback inside app.Map.

app.UseEndpoints(endpoints =>
{
    endpoints.MapGrpcService<LocationsServiceV1>().EnableGrpcWeb();

    endpoints.MapControllers();
    endpoints.MapRazorPages();
});

app.Map("",
    builder =>
    {
        builder.UseRouting();
        builder.UseEndpoints(endpoints =>
        {
            // Fallback for blazor front-end
            endpoints.MapFallbackToAreaPage("{*path:nonfile}", "/_Host", "Frontend");
        });
    });
Jiri Sykora
  • 454
  • 4
  • 10