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

Kar*_*loX 5 c# asp.net-core asp.net-core-webapi blazor-server-side

我想同时实现

  • ASP.NET Core Blazor 服务器
  • 和 ASP.NET Core Web API(服务器部分,而不是消费者/客户端)

在同一进程中使用 .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();
Run Code Online (Sandbox Code Playgroud)

对于 ASP.NET Core 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();
Run Code Online (Sandbox Code Playgroud)

那么问题是如何将这两者合而为一?

我想要:

  • 让我的程序监听单个端口
  • 托管 Blazor 网页
  • 但在访问URL myhost:port/api/..时处理 API (不干扰 Blazor 部分)
  • 有 SwaggerUI,最好在myhost:port/api/swagger/index.html下下(同样不干扰 Blazor 部分)
  • 两者使用基于客户端证书的相同安全机制

pok*_*oke 7

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

\n
var builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddRazorPages();\nbuilder.Services.AddServerSideBlazor();\nbuilder.Services.AddSingleton<WeatherForecastService>();\nbuilder.Services.AddControllers();\nbuilder.Services.AddEndpointsApiExplorer();\nbuilder.Services.AddSwaggerGen();\n\nvar app = builder.Build();\n\nif (app.Environment.IsDevelopment())\n{\n    app.UseSwagger();\n    app.UseSwaggerUI();\n}\nelse\n{\n    app.UseExceptionHandler("/Error");\n    app.UseHsts();\n}\n\napp.UseHttpsRedirection();\napp.UseStaticFiles();\napp.UseAuthorization();\n\napp.UseRouting();\napp.MapControllers();\napp.MapBlazorHub();\napp.MapFallbackToPage("/_Host");\n\napp.Run();\n
Run Code Online (Sandbox Code Playgroud)\n

无论如何,服务配置支持注册所有依赖项。无论如何,在 和 之间AddRazorPages(),AddController()有相当多的共享内容。

\n

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

\n

好处是这MapControllers通常意味着一组固定的路线。由于您的控制器操作具有特定的路由,因此拥有MapControllers第一个将确保您的控制器能够正确处理这些特定的路由。

\n

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

\n

所以最后,所有剩余的请求都将落在MapFallbackToPage()。这是一个后备处理程序,这意味着它将处理任何路由。这允许 Blazor 拥有一个入口点,然后将为其使用客户端路由。只要此回退调用是管道中的最后一个,它就不能干扰任何其他路由处理程序。

\n

通过这种组合配置,您的 API 和 Blazor 都应该可以正常工作。

\n

如果您确实遇到更复杂的情况,那么您可以使用app.MapWhen来分支管道。如果您对此功能感兴趣,文档中有一个示例。但正如我所说,对于你的情况,你不应该\xe2\x80\x99 需要它。

\n