StringContent与JsonContent.Create差异及适配方案技术问询
问题
以下代码可正常运行并返回200 OK:
var json = JsonConvert.SerializeObject(obj); var content = new StringContent(json); var httpResponse = await httpClient.PostAsync("", content); // 200 OK
但使用JsonContent.Create的写法会返回500 Internal Server Error:
var content = JsonContent.Create(obj); var httpResponse = await httpClient.PostAsync("", content); // 500 Internal Server Error
请问JsonContent的序列化/编码方式和前者存在哪些差异?能否通过配置让第二种写法的表现与第一种完全一致?已知第一种写法可行,需明确第二种写法失效的原因。
相关对象定义如下:
请求对象实例:
var obj = new AccountLookupService.GetUserOnlineProfileRequest { ContractAccountNumber = "100087751101", Address = new ServiceAddress { HouseNumber = string.Empty, StreetName = string.Empty, HouseNumberSupplement = string.Empty, City = string.Empty, State = string.Empty, ZipCode = "48386", }, Phone = string.Empty, Name = string.Empty, };
请求对象类定义:
public class GetUserOnlineProfileRequest { public string? ContractAccountNumber { get; set; } public ServiceAddress? Address { get; set; } public string? Phone { get; set; } public string? Name { get; set; } public int AccountLimit { get; set; } = 10; }
地址类定义:
public class ServiceAddress { public string? HouseNumber { get; set; } public string? StreetName { get; set; } public string? HouseNumberSupplement { get; set; } public string? City { get; set; } public string? State { get; set; } public string? ZipCode { get; set; } }
原因分析与解决方案
核心差异
两种写法的本质区别在于依赖的序列化库和默认配置不同:
- 第一种写法使用
JsonConvert(Newtonsoft.Json库),第二种写法的JsonContent默认依赖.NET内置的System.Text.Json库。 - 最关键的差异点是属性命名策略:
- Newtonsoft.Json默认保留类的原属性名(PascalCase,即首字母大写);
- System.Text.Json默认采用驼峰命名策略(camelCase,即首字母小写)。
- 次要差异是
Content-Type:StringContent默认的Content-Type是text/plain; charset=utf-8,但服务器可能兼容解析这种类型下的JSON;JsonContent默认的Content-Type是标准的application/json; charset=utf-8,但由于属性名格式不匹配,服务器无法正确解析参数,最终返回500错误。
配置JsonContent与Newtonsoft.Json行为一致
要让JsonContent.Create的表现和JsonConvert.SerializeObject默认一致,只需指定JsonSerializerOptions调整序列化规则:
var serializerOptions = new JsonSerializerOptions { // 禁用驼峰命名,保留原属性名(和Newtonsoft.Json默认一致) PropertyNamingPolicy = null, // 序列化所有属性,包括值类型的非默认值(和Newtonsoft.Json默认行为对齐) DefaultIgnoreCondition = JsonIgnoreCondition.Never, // 不忽略空值/空字符串,确保空字符串被正确序列化(和Newtonsoft.Json一致) IgnoreNullValues = false }; var content = JsonContent.Create(obj, options: serializerOptions); var httpResponse = await httpClient.PostAsync("", content);
验证差异
分别输出两种方式的序列化结果就能直观看到区别:
- Newtonsoft.Json序列化结果(第一种写法的JSON):
{ "ContractAccountNumber": "100087751101", "Address": { "HouseNumber": "", "StreetName": "", "HouseNumberSupplement": "", "City": "", "State": "", "ZipCode": "48386" }, "Phone": "", "Name": "", "AccountLimit": 10 }
- 默认System.Text.Json序列化结果(第二种写法的JSON):
{ "contractAccountNumber": "100087751101", "address": { "houseNumber": "", "streetName": "", "houseNumberSupplement": "", "city": "", "state": "", "zipCode": "48386" }, "phone": "", "name": "", "accountLimit": 10 }
属性名的大小写差异是导致服务器解析失败的直接原因。
内容的提问来源于stack exchange,提问作者Mark Good
相关产品推荐
相关产品推荐

