WPF桌面应用如何发送application/x-www-form-urlencoded格式POST请求
C# WPF 调用application/x-www-form-urlencoded格式POST接口实现方案
初始代码存在的问题
- ContentType值拼写错误,多了多余的横杠,正确值为
application/x-www-form-urlencoded - 手动给HttpContent赋值字符串是错误用法,
FormUrlEncodedContent本身已经支持自动将键值对转换为符合要求的请求体格式 - 构造Uri时传入的地址缺少字符串引号,存在语法错误
- 仅完成了请求参数、客户端的初始化,没有实际执行POST请求的逻辑
可运行版本优化方向
你后续调试得到的版本已经可以完成基础请求,可针对生产使用做以下优化:
- HttpClient单例化:每次请求新建HttpClient会导致套接字资源耗尽,建议在APIHelper中定义静态全局HttpClient实例
- 改用异步写法:直接调用
.Result会阻塞UI线程,还可能引发死锁,WPF场景下优先用async/await异步调用 - 增加响应内容解析逻辑:当前代码仅输出了响应对象,没有解析返回的JSON业务数据,需要读取响应内容后反序列化为对应的实体类
优化后完整实现代码
1. 实体类与API工具类定义
using System; using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; // 自定义返回结果实体类,可根据接口实际返回字段调整 public class IndividualSearchResult { // 示例字段,根据实际接口返回修改 public string Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime UpdatedDTM { get; set; } } public class APIHelper { // 全局单例HttpClient,避免多次实例化引发的资源问题 private static readonly HttpClient _httpClient = new HttpClient(); /// <summary> /// 调用AgencyBloc搜索接口 /// </summary> /// <param name="sid">安全凭证sid</param> /// <param name="key">安全凭证key</param> /// <param name="updatedDTM">更新时间筛选参数</param> /// <param name="lastName">姓氏筛选参数</param> /// <returns>搜索结果列表</returns> public static async Task<List<IndividualSearchResult>> BlocCallAsync(string sid, string key, string updatedDTM = null, string lastName = null) { var parameters = new Dictionary<string, string> { {"sid", sid}, {"key", key} }; // 按需添加可选筛选参数 if (!string.IsNullOrEmpty(updatedDTM)) parameters.Add("updatedDTM", updatedDTM); if (!string.IsNullOrEmpty(lastName)) parameters.Add("lastName", lastName); var request = new HttpRequestMessage(HttpMethod.Post, "https://app.agencybloc.com/api/v1/individuals/search/") { Content = new FormUrlEncodedContent(parameters) }; // 配置无需缓存的请求头 request.Headers.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue { NoCache = true }; var response = await _httpClient.SendAsync(request); // 请求失败时直接抛出异常,可根据业务需要调整错误处理逻辑 response.EnsureSuccessStatusCode(); // 读取响应JSON内容 var responseJson = await response.Content.ReadAsStringAsync(); // 反序列化得到业务结果 return JsonConvert.DeserializeObject<List<IndividualSearchResult>>(responseJson); } }
2. 按钮点击异步调用代码
private async void Button_Click(object sender, RoutedEventArgs e) { try { // 调用接口获取第一批数据 var firstResult = await APIHelper.BlocCallAsync("你的SID", "你的Key", updatedDTM: "09/20/2021"); // 业务处理:如绑定到UI、提取参数发起第二次请求 // 如需发起第二次请求,直接复用BlocCallAsync方法传入对应参数即可 // var secondResult = await APIHelper.BlocCallAsync("你的SID", "你的Key", lastName: "Heine"); } catch (Exception ex) { // 异常处理,如弹出错误提示 MessageBox.Show($"接口请求失败:{ex.Message}"); } }
内容的提问来源于stack exchange,提问作者Nathan Elkind
相关产品推荐
相关产品推荐

