You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server项目:直接访问数据库还是调用自研ASP.NET Core WebAPI?

推荐方案与分析

先明确两个方案的核心问题

直接访问数据库的隐患

  • 重复配置维护成本高:如果在Blazor Server里复制WebAPI的DbContext、DI服务配置,后续Infrastructure类库更新(比如新增仓储实现、修改DbContext配置),你需要同时修改两个项目的Program.cs,极易出现配置不一致的问题,长期维护会非常头疼。
  • 打破分层架构边界:你的Core+Infrastructure本来是业务逻辑的核心封装,WebAPI作为对外的网关层负责权限校验、请求限流、响应封装等通用逻辑。Blazor直接连DB等于跳过了这些网关能力,后续如果要加移动端、小程序等客户端,你需要在Blazor里重复实现这些逻辑,完全违背了架构复用的初衷。
  • 安全风险提升:Blazor Server服务器需要直接持有数据库连接字符串,增加了数据库的暴露面;同时所有业务逻辑的权限校验要在Blazor里重新实现,容易出现权限漏洞。

调用WebAPI的性能顾虑其实被放大了

Blazor Server是服务器端运行的,你可以配置HttpClient直接调用本地部署的WebAPI(比如http://localhost:5000),这种内部请求的性能损耗极低——没有公网延迟,只是本地进程间的HTTP通信,几乎可以忽略。如果还是担心,还可以做以下优化:

  • 用IHttpClientFactory复用HttpClient实例,避免频繁创建销毁的开销。
  • 启用HTTP/2协议,提升请求响应效率。
  • 对请求响应启用Gzip压缩,减少数据传输量。

最优解:复用业务服务层,避免重复配置+跳过HTTP损耗

既然你已经有了Core(领域模型+接口)和Infrastructure(接口实现)的分层,完全可以让Blazor Server直接依赖这两个类库,复用业务逻辑层,同时解决重复配置的问题:

步骤1:封装DI配置到扩展方法

在Infrastructure类库中创建一个扩展方法,把所有需要注册的服务(DbContext、仓储实现、业务服务等)统一封装:

// Infrastructure类库中的扩展方法
public static class InfrastructureServiceExtensions
{
    public static IServiceCollection AddInfrastructureServices(this IServiceCollection services, IConfiguration configuration)
    {
        // 配置DbContext
        services.AddDbContext<AppDbContext>(options =>
            options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
        
        // 注册仓储实现
        services.AddScoped<IUserRepository, UserRepository>();
        services.AddScoped<IOrderRepository, OrderRepository>();
        
        // 注册其他业务服务
        services.AddScoped<IUserService, UserService>();
        
        return services;
    }
}

步骤2:在WebAPI和Blazor中复用配置

不管是WebAPI还是Blazor Server的Program.cs,只需要一行代码即可完成所有基础设施服务的注册:

// WebAPI/Blazor Server的Program.cs
builder.Services.AddInfrastructureServices(builder.Configuration);

这样就完全避免了重复编写组合根的问题,后续Infrastructure的配置更新,只需要修改扩展方法,两个项目自动同步。

步骤3:Blazor直接调用业务服务

在Blazor组件中直接注入Core层定义的业务接口,调用业务逻辑,完全跳过HTTP请求:

@inject IUserService UserService

<h3>用户列表</h3>
@if (Users != null)
{
    foreach (var user in Users)
    {
        <p>@user.Name</p>
    }
}

@code {
    private List<User>? Users;

    protected override async Task OnInitializedAsync()
    {
        Users = await UserService.GetAllUsersAsync();
    }
}

什么时候需要调用WebAPI?

如果你的Blazor Server需要和WebAPI部署在不同的服务器(比如WebAPI在云服务器,Blazor Server在本地),或者未来计划支持Blazor WebAssembly(客户端运行,必须通过HTTP调用API),这时候才需要统一通过WebAPI来访问业务逻辑。但即便如此,也可以在Blazor中封装一个API客户端类,统一处理HTTP请求,避免重复编写HttpClient调用代码。


内容的提问来源于stack exchange,提问作者DM-98

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 01:39:40