如何在同一进程中实现 ASP.NET Core Blazor Server 应用程序和 Web API 应用程序?

Howto implement ASP.NET Core Blazor Server app and a Web API app in the same procress?

我想实现两者

在使用 .NET 6 的相同 进程中,运行 它使用 Kestrel 自托管,即没有 IIS。

我认为关键是在相应的 Program.cs 模板中找到的服务和中间件管道配置。这是 VS 2022 (17.1.5) 为我创建的两个模板:

对于 Blazor 服务器应用:

using BlazorApp1.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
  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.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

对于 ASP.NET 核心 Web API 应用程序:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
  app.UseSwagger();
  app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

所以问题是如何将这两者合二为一?

我想:

您应该能够毫无问题地组合这些:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseRouting();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

服务配置无论如何都支持注册所有依赖项。而且在AddRazorPages()AddController()之间,反正共享的还是蛮多的

唯一棘手的事情是管道配置,因为您需要确保 API 请求和 Blazor 请求都由正确的处理程序处理。

好处是MapControllers通常表示一组固定的路由。由于您的控制器操作具有特定路线,因此首先使用 MapControllers 将确保您的控制器能够正确处理这些特定路线。

所有其他请求,那些不匹配任何控制器操作的请求,将转到管道中的下一个路由处理程序。因此 MapBlazorHub 接下来是托管 Blazor 的 SignalR 中心。这也是一个非常具体的路线,在这里提供。

所以最后,所有剩余的请求都将到达 MapFallbackToPage()。这是一个 fallback-handler 这意味着它将处理 any 路由。这允许 Blazor 有一个 entry-point 然后它将使用 client-side 路由。只要这个回退调用是管道中的最后一个,它就不能干扰任何其他路由处理程序。

使用该组合配置,您的 API 和 Blazor 应该都能正常工作。

如果您确实遇到了更复杂的情况,如果您对此功能感兴趣,则可以使用 app.MapWhen to branch off the pipeline. There is an example in the documentation。但正如我所说,对于你的情况,你不应该需要它。