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

如何在ASP.NET ZERO(Angular+ASP.Net Core模板)中实现API版本控制?

我刚好有过在ASP.NET Zero(Angular+ASP.NET Core)里实现API版本控制的实战经验,给你一步步拆解具体操作,确保v1和v2版本能同时稳定运行:


后端(ASP.NET Core)实现步骤

1. 安装API版本控制依赖

在你的Web.Core项目里,先安装Microsoft.AspNetCore.Mvc.Versioning包——用.NET CLI的话直接跑命令:

dotnet add package Microsoft.AspNetCore.Mvc.Versioning

2. 配置API版本控制服务

打开Program.cs(.NET 6+)或者Startup.cs,在服务配置段添加以下代码,告诉系统我们要通过URL路径识别版本:

builder.Services.AddApiVersioning(options =>
{
    // 让响应头返回当前支持的所有API版本,方便前端排查问题
    options.ReportApiVersions = true;
    // 如果请求没指定版本,默认使用v1.0
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
    // 指定从URL中的版本段(比如v2)读取版本号
    options.ApiVersionReader = new UrlSegmentApiVersionReader();
});

3. 保留原有v1 API的兼容性

原来的/api/services/app/Customer/GetAll要继续可用,同时支持带v1的路径/api/services/app/v1/Customer/GetAll,分两种场景处理:

如果你是手动编写控制器

给控制器添加双路由特性,并标记版本:

[ApiVersion("1.0")]
// 同时支持无版本和带v1的路由
[Route("api/services/app/[controller]/[action]")]
[Route("api/services/app/{version:apiVersion}/[controller]/[action]")]
public class CustomerController : AbpController, ICustomerAppService
{
    // 原有v1的GetAll逻辑保持不变
    public async Task<PagedResultDto<CustomerDto>> GetAll(GetAllCustomersInput input)
    {
        // ... 你的业务代码
    }
}

如果你用ABP动态生成API(基于AppService)

直接给CustomerAppService添加路由特性即可:

[ApiVersion("1.0")]
[Route("api/services/app/Customer/[action]")]
[Route("api/services/app/{version:apiVersion}/Customer/[action]")]
public class CustomerAppService : ApplicationService, ICustomerAppService
{
    // ... 原有逻辑无需改动
}

4. 搭建v2版本的API

推荐用独立的AppService/控制器实现v2,避免和v1代码混杂,后续维护更清晰:

  1. 创建v2专属DTO:比如CustomerV2Dto、GetAllCustomersV2Input,根据v2需求调整字段(比如新增返回字段、修改参数规则)。
  2. 编写v2的AppService:
[ApiVersion("2.0")]
// 直接指定v2的路由前缀
[Route("api/services/app/v2/Customer/[action]")]
public class CustomerV2AppService : ApplicationService, ICustomerV2AppService
{
    public async Task<PagedResultDto<CustomerV2Dto>> GetAll(GetAllCustomersV2Input input)
    {
        // 这里编写v2版本的业务逻辑,比如优化查询、返回更多数据
    }
}

ABP默认会扫描项目内所有AppService生成API,无需额外配置,只要类存在就能被识别。

如果v2改动极小,也可以在同一控制器内用版本标记区分方法:

[ApiVersion("1.0")]
[ApiVersion("2.0")]
[Route("api/services/app/{version:apiVersion}/[controller]/[action]")]
[Route("api/services/app/[controller]/[action]")] // 无版本请求默认走v1
public class CustomerController : AbpController
{
    // v1版本的GetAll
    [MapToApiVersion("1.0")]
    public async Task<PagedResultDto<CustomerDto>> GetAll(GetAllCustomersInput input)
    {
        // ... v1逻辑
    }

    // v2版本的GetAll
    [MapToApiVersion("2.0")]
    public async Task<PagedResultDto<CustomerV2Dto>> GetAll(GetAllCustomersV2Input input)
    {
        // ... v2逻辑
    }
}

这种方式要确保方法参数不同,避免路由冲突。


前端(Angular)实现步骤

1. 复制并改造v2的服务和DTO

  • 复制现有customer.service.ts为customer-v2.service.ts,修改请求URL为v2路径:
import { Injectable } from '@angular/core';
import { AppServiceBase } from '@shared/service-proxies/app-service-base';
import { Observable } from 'rxjs';
import { PagedResultDto } from '@shared/service-proxies/dto/paged-result-dto';
import { GetAllCustomersV2Input, CustomerV2Dto } from './dto/customer-v2-dto';

@Injectable({ providedIn: 'root' })
export class CustomerV2Service extends AppServiceBase {
    getAll(input: GetAllCustomersV2Input): Observable<PagedResultDto<CustomerV2Dto>> {
        return this.request({
            url: '/api/services/app/v2/Customer/GetAll',
            method: 'POST',
            body: input
        });
    }
}
  • 创建customer-v2-dto.ts,定义和后端完全匹配的v2 DTO结构。

2. 在组件中使用v2服务

在需要调用v2 API的组件里,注入CustomerV2Service即可:

import { Component } from '@angular/core';
import { CustomerV2Service } from './customer-v2.service';
import { GetAllCustomersV2Input } from './dto/customer-v2-dto';

@Component({
    selector: 'app-customer-v2',
    templateUrl: './customer-v2.component.html'
})
export class CustomerV2Component {
    constructor(private _customerV2Service: CustomerV2Service) {}

    loadCustomers() {
        const input = new GetAllCustomersV2Input();
        // 按需设置参数
        this._customerV2Service.getAll(input).subscribe(result => {
            // 处理v2返回的数据
        });
    }
}

测试验证

  • 调用v1:POST /api/services/app/Customer/GetAll 或 POST /api/services/app/v1/Customer/GetAll,确认返回v1格式的数据。
  • 调用v2:POST /api/services/app/v2/Customer/GetAll,确认返回v2格式的数据。
  • 查看响应头中的api-supported-versions,应该能看到1.0和2.0,说明版本配置生效。

内容的提问来源于stack exchange,提问作者devson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:33:15