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

如何从API收集的数据中发送指定字段至其他项目?

我看了你代码里的问题了——你现在在PostWatchdogData里犯了两个关键错误:一是把整个List<ServerStateDto>直接转成字符串赋值给单个WatchdogDTO的id,这肯定只会发送列表的类型名称而不是实际数据;二是你应该发送DTO列表(对应原数据的每一条),而不是单个DTO对象。

下面给你分步解决,不管你要发送单个字段(比如id)还是多个字段组合(id+HostName)都适用:


1. 按需调整WatchdogDTO模型

如果只需要发送id,保持原模型不变;如果要发送id+HostName,就给DTO添加对应字段:

// 单个字段(id)版本
public class WatchdogDTO {
    public string id { get; set; }
}

// 多字段(id+HostName)版本
public class WatchdogDTO {
    public string id { get; set; }
    public string HostName { get; set; } // 新增需要发送的字段
}

2. 修复WatchdogApiClient的发送方法

这里的核心是把原数据集合映射成目标DTO集合,然后序列化整个列表发送,同时修正async void的不良写法(改成async Task方便错误处理和等待):

public class WatchdogApiClient {
    private static readonly HttpClient client = new HttpClient();

    // 把async void改为async Task,避免异步方法的潜在问题
    public async Task PostWatchdogData(List<ServerStateDto> toSend) {
        // 先判断原数据是否为空
        if (toSend == null || !toSend.Any()) {
            Console.WriteLine("No data to send");
            return;
        }

        // 用LINQ把原数据映射成目标DTO列表,只保留需要的字段
        var toActuallySend = toSend.Select(item => new WatchdogDTO {
            id = item.id,
            // 如果要发送HostName,取消下面这行注释
            // HostName = item.HostName
        }).ToList();

        // 序列化整个DTO列表
        string serializedWatchDogData = JsonConvert.SerializeObject(toActuallySend);
        if (string.IsNullOrEmpty(serializedWatchDogData)) {
            Console.WriteLine("Failed to serialize data");
            return;
        }

        try {
            var response = await client.PostAsync(
                "http://localhost:53661/api/Values",
                new StringContent(serializedWatchDogData, Encoding.UTF8, "application/json")
            );
            // 可选:确保请求成功,失败时抛出异常
            response.EnsureSuccessStatusCode();
        } catch (Exception ex) {
            Console.WriteLine($"Encountered an exception during PostAsync: {ex.Message}");
            throw; // 保留原始异常堆栈,方便调试
        }
    }
}

3. 修改调用发送方法的代码

因为现在发送方法是async Task,所以调用方也要改成异步方法并使用await等待完成:

// 把原来的bool Start改成async Task<bool>
public async Task<bool> Start(HostControl hostControl) {
    ApiManager x = new ApiManager();
    List<ServerStateDto> returnedData = x.CollectWatchdogData();
    if (returnedData == null) {
        return false;
    }
    WatchdogApiClient cli = new WatchdogApiClient();
    await cli.PostWatchdogData(returnedData); // 必须用await等待异步操作完成
    return true;
}

4. 调整接收端的控制器

因为现在发送的是DTO列表,所以接收参数要改成List<WatchdogDTO>,不然会解析失败:

public class ValuesController : ApiController {
    [HttpPost]
    public void PostWatchdogData([FromBody] List<WatchdogDTO> data) {
        var hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
        // 遍历接收的每个DTO,处理并广播
        foreach (var item in data) {
            // 比如广播id,或者组合id和HostName
            string message = $"Server ID: {item.id}";
            if (!string.IsNullOrEmpty(item.HostName)) {
                message += $", HostName: {item.HostName}";
            }
            hubContext.Clients.All.BroadcastMessage("Server", message);
        }
    }
}

关键说明:

  • 映射数据:用Select遍历原数据,只提取需要的字段到DTO,这样能确保发送的数据是精简且符合要求的。
  • 序列化列表:这样发送的JSON是数组格式(和你收集的原数据结构一致),接收端可以正确解析为列表。
  • 异步规范:避免用async void,改用async Task,这样调用方可以等待操作完成,也能正确捕获异常。

这样调整后,你就能成功发送指定的单个或多个字段到目标项目了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:16:02