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

C#中如何实现合并两个REST端点结果的第三方端点?

最优实现方案

首先,不建议先调用端点A再用返回的ID调用端点B——如果用户传入的是城市名称(无ID),串行调用会增加请求延迟;如果是ID列表,重复调用B也会浪费资源。更优的方式是:

  • 直接使用当前端点接收到的请求参数(城市名/城市名+ID列表),并行调用端点A和端点B,同时获取两组数据
  • 以公司ID为唯一标识,将两组数据进行合并

这种方式能减少总请求耗时(并行比串行更快),逻辑清晰,也能完整保留端点A的原始数据。

具体实现步骤(C#)

假设你基于ASP.NET Core开发:

1. 定义强类型数据模型(推荐)

为三个端点的返回数据定义DTO(数据传输对象),保证类型安全:

// 端点A返回的企业基础信息
public class CompanyBasicInfo
{
    public int CompanyId { get; set; }
    public string CompanyName { get; set; }
    public string Address { get; set; }
    public string Contact { get; set; }
}

// 端点B返回的企业经营信息
public class CompanyBusinessInfo
{
    public int CompanyId { get; set; }
    public string StructureType { get; set; }
    public int EmployeeCount { get; set; }
    public decimal Revenue { get; set; }
}

// 合并后的最终返回模型
public class CompanyCombinedInfo
{
    public int CompanyId { get; set; }
    public string CompanyName { get; set; }
    public string Address { get; set; }
    public string Contact { get; set; }
    public string StructureType { get; set; }
    public int EmployeeCount { get; set; }
    public decimal Revenue { get; set; }
}

2. 并行调用并合并数据

利用HttpClient发起请求,通过Task.WhenAll实现并行调用,再用LINQ合并结果:

private readonly HttpClient _httpClient;

// 构造函数注入HttpClient
public YourController(HttpClient httpClient)
{
    _httpClient = httpClient;
}

[HttpGet("combined-company-info")]
public async Task<IActionResult> GetCombinedInfo(string city, List<int> companyIds = null)
{
    // 构造请求参数(与A、B端点参数格式一致)
    var queryParams = new Dictionary<string, string>
    {
        { "city", city }
    };
    if (companyIds?.Any() == true)
    {
        queryParams.Add("companyIds", string.Join(",", companyIds));
    }

    // 构建A、B端点的请求URL(根据实际地址调整)
    var urlBuilder = new UriBuilder("https://your-api-domain.com/api/endpointA");
    urlBuilder.Query = new FormUrlEncodedContent(queryParams).ReadAsStringAsync().Result;
    var urlA = urlBuilder.ToString();
    var urlB = urlBuilder.ToString().Replace("endpointA", "endpointB");

    // 并行调用两个端点,减少等待时间
    var taskGetBasic = _httpClient.GetFromJsonAsync<List<CompanyBasicInfo>>(urlA);
    var taskGetBusiness = _httpClient.GetFromJsonAsync<List<CompanyBusinessInfo>>(urlB);
    await Task.WhenAll(taskGetBasic, taskGetBusiness);

    var basicInfos = taskGetBasic.Result;
    var businessInfos = taskGetBusiness.Result;

    // 用CompanyId关联合并数据
    var combinedResult = basicInfos.Join(
        businessInfos,
        basic => basic.CompanyId,
        business => business.CompanyId,
        (basic, business) => new CompanyCombinedInfo
        {
            CompanyId = basic.CompanyId,
            CompanyName = basic.CompanyName,
            Address = basic.Address,
            Contact = basic.Contact,
            StructureType = business.StructureType,
            EmployeeCount = business.EmployeeCount,
            Revenue = business.Revenue
        }).ToList();

    return Ok(combinedResult);
}
简便的JSON动态合并方法

如果不想用强类型(不推荐,缺乏类型安全),可以用JSON库直接合并JSON对象:

方法1:使用Newtonsoft.Json(Json.NET)

// 获取A、B端点的JSON字符串
string jsonBasic = await _httpClient.GetStringAsync(urlA);
string jsonBusiness = await _httpClient.GetStringAsync(urlB);

var jArrayBasic = JArray.Parse(jsonBasic);
var jArrayBusiness = JArray.Parse(jsonBusiness);

// 将B的结果转成以CompanyId为键的字典,方便快速查找
var businessDict = jArrayBusiness.ToDictionary(j => (int)j["CompanyId"], j => j);

var combinedArray = new JArray();
foreach (var basicObj in jArrayBasic)
{
    int companyId = (int)basicObj["CompanyId"];
    if (businessDict.TryGetValue(companyId, out var businessObj))
    {
        // 合并两个JObject,跳过重复的CompanyId
        var combinedObj = new JObject(basicObj);
        foreach (var prop in businessObj.Properties())
        {
            if (prop.Name != "CompanyId")
            {
                combinedObj[prop.Name] = prop.Value;
            }
        }
        combinedArray.Add(combinedObj);
    }
}

return Ok(combinedArray);

方法2:使用System.Text.Json(.NET Core 3.0+内置)

string jsonBasic = await _httpClient.GetStringAsync(urlA);
string jsonBusiness = await _httpClient.GetStringAsync(urlB);

var jsonArrayBasic = JsonNode.Parse(jsonBasic) as JsonArray;
var jsonArrayBusiness = JsonNode.Parse(jsonBusiness) as JsonArray;

// 构建B结果的字典
var businessDict = jsonArrayBusiness.ToDictionary(
    node => (int)node["CompanyId"],
    node => node as JsonObject);

var combinedArray = new JsonArray();
foreach (var basicNode in jsonArrayBasic)
{
    var basicObj = basicNode as JsonObject;
    int companyId = (int)basicObj["CompanyId"];
    if (businessDict.TryGetValue(companyId, out var businessObj))
    {
        // 合并对象
        var combinedObj = new JsonObject();
        // 添加基础信息
        foreach (var kvp in basicObj)
        {
            combinedObj.Add(kvp.Key, kvp.Value);
        }
        // 添加经营信息(跳过重复键)
        foreach (var kvp in businessObj)
        {
            if (!combinedObj.ContainsKey(kvp.Key))
            {
                combinedObj.Add(kvp.Key, kvp.Value);
            }
        }
        combinedArray.Add(combinedObj);
    }
}

return Ok(combinedArray);
注意事项
  • 异常处理:给HttpClient调用添加try-catch,处理端点请求失败、数据解析错误等情况
  • 空值兼容:合并时要考虑某公司在A或B中不存在的场景,可选择跳过该条目或填充默认值
  • 参数一致性:确保传给A、B的请求参数完全一致,避免出现数据不匹配问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 11:25:26