WinForm C#中如何向REST API POST接口发送带列表与参数的JSON请求
问题分析与解决方案
原代码核心错误点
- requestData初始化语法错误:错误地将对象实例化与JSON字符串拼接混合,直接导致编译失败。
- 属性大小写不匹配:模型类中
retailercode为全小写,但代码中写为RetailerCode,序列化后的JSON键名与API要求不符,接口无法正确解析参数。 - HttpClient使用不当:每次请求新建HttpClient实例,违反.NET最佳实践,易引发连接资源泄漏。
- 异步方法设计不合理:
async void仅适合事件处理场景,改为async Task能更规范地处理异步流程与异常。
修正后的完整代码
1. 优化模型类(明确控制JSON键名)
通过特性绑定JSON键名,同时遵循C#命名规范:
using System.Text.Json.Serialization; using System.Collections.Generic; public class Root0 { [JsonPropertyName("retailercode")] public string RetailerCode { get; set; } [JsonPropertyName("orderitems")] public List<OrderItem0> OrderItems { get; set; } } public class OrderItem0 { [JsonPropertyName("rownumber")] public int RowNumber { get; set; } [JsonPropertyName("productcode")] public string ProductCode { get; set; } [JsonPropertyName("qty")] public decimal Qty { get; set; } // 以下为响应返回字段,请求时无需赋值 [JsonPropertyName("orderprice")] public decimal OrderPrice { get; set; } [JsonPropertyName("percentdisc")] public string PercentDisc { get; set; } [JsonPropertyName("disreg")] public decimal Disreg { get; set; } [JsonPropertyName("valuediscreg")] public decimal ValueDiscreg { get; set; } [JsonPropertyName("totaldisc")] public decimal TotalDisc { get; set; } }
2. 修正请求方法与事件逻辑
using System; using System.Threading.Tasks; using System.Net.Http; using System.Text; using System.Text.Json; using System.Windows.Forms; // 全局复用HttpClient实例,避免资源浪费 private static readonly HttpClient _httpClient = new HttpClient(); public async Task Coba5Async() { try { string url = "https://localhost:44328/api/hitung"; // 正确构建请求数据对象 var requestData = new Root0 { RetailerCode = "CJF00055", OrderItems = new List<OrderItem0> { new OrderItem0 { RowNumber = 1, ProductCode = "100535", Qty = 5 } } }; // 配置序列化选项,保证JSON格式匹配API要求 var serializeOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true // 可选,格式化JSON方便调试 }; string json = JsonSerializer.Serialize(requestData, serializeOptions); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await _httpClient.PostAsync(url, content); // 主动校验请求是否成功,失败时抛出异常 response.EnsureSuccessStatusCode(); string responseContent = await response.Content.ReadAsStringAsync(); // 可选:将响应反序列化为模型对象,方便业务处理 var result = JsonSerializer.Deserialize<Root0>(responseContent, serializeOptions); MessageBox.Show(responseContent); } catch (HttpRequestException ex) { MessageBox.Show($"请求错误:{ex.Message}"); } catch (JsonException ex) { MessageBox.Show($"JSON序列化/反序列化错误:{ex.Message}"); } catch (Exception ex) { MessageBox.Show($"未知错误:{ex.ToString()}"); } } private async void button2_Click(object sender, EventArgs e) { await Coba5Async(); }
关键修正说明
- 规范对象初始化:用C#对象初始化语法构建请求数据,避免直接拼接JSON字符串的低级错误。
- 对齐JSON键名:通过
JsonPropertyName特性或序列化配置,确保生成的JSON键名与API要求完全一致。 - 复用HttpClient:全局静态实例避免频繁创建销毁引发的连接资源问题。
- 细化异常处理:分类型捕获请求、序列化相关异常,便于快速定位问题。
- 优化异步流程:将
async void改为async Task,在事件方法中用await调用,保证异步逻辑正确执行。
内容的提问来源于stack exchange,提问作者anto
相关产品推荐
相关产品推荐

