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

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();
}

关键修正说明

  1. 规范对象初始化:用C#对象初始化语法构建请求数据,避免直接拼接JSON字符串的低级错误。
  2. 对齐JSON键名:通过JsonPropertyName特性或序列化配置,确保生成的JSON键名与API要求完全一致。
  3. 复用HttpClient:全局静态实例避免频繁创建销毁引发的连接资源问题。
  4. 细化异常处理:分类型捕获请求、序列化相关异常,便于快速定位问题。
  5. 优化异步流程:将async void改为async Task,在事件方法中用await调用,保证异步逻辑正确执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 03:17:49