如何从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
相关产品推荐
相关产品推荐

