如何在同一进程中实现 ASP.NET Core Blazor Server 应用程序和 Web API 应用程序?
Howto implement ASP.NET Core Blazor Server app and a Web API app in the same procress?
我想实现两者
- a ASP.NET 核心 Blazor 服务器
- 和一个 ASP.NET 核心 Web API(服务器部分,不是 consumer/client)
在使用 .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();
所以问题是如何将这两者合二为一?
我想:
- 让我的程序监听一个端口
- 托管 Blazor 网页
- 但是在 URL myhost:port/api/.. 被访问时处理 API (不干扰 Blazor 部分)
- 有SwaggerUI,最好在myhost:port/api/swagger/index.html下(同样不干扰Blazor部分)
- 对两者使用基于客户端证书的相同安全机制
您应该能够毫无问题地组合这些:
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。但正如我所说,对于你的情况,你不应该需要它。
我想实现两者
- a ASP.NET 核心 Blazor 服务器
- 和一个 ASP.NET 核心 Web API(服务器部分,不是 consumer/client)
在使用 .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();
所以问题是如何将这两者合二为一?
我想:
- 让我的程序监听一个端口
- 托管 Blazor 网页
- 但是在 URL myhost:port/api/.. 被访问时处理 API (不干扰 Blazor 部分)
- 有SwaggerUI,最好在myhost:port/api/swagger/index.html下(同样不干扰Blazor部分)
- 对两者使用基于客户端证书的相同安全机制
您应该能够毫无问题地组合这些:
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。但正如我所说,对于你的情况,你不应该需要它。