.NET 6 Web Service如何在JSON中传递嵌套JSON字符串?
解决.NET 6 Web服务中嵌套JSON字符串的反序列化问题
问题根源
你当前传递的address字段值存在两处不符合JSON规范的问题,直接导致整个请求JSON解析失败,控制器无法绑定到Director对象,最终得到null:
- 嵌套JSON内部使用了单引号,而JSON要求字符串必须用双引号包裹
- 嵌套JSON末尾多了逗号,且整个字符串未正确转义内部的双引号
方案一:客户端传递规范转义的JSON字符串
将嵌套JSON转换为符合JSON规范的字符串,需完成以下操作:
- 把内部所有双引号转义(用
\"替代") - 移除多余的末尾逗号
- 统一用双引号包裹键和值
正确的请求JSON示例:
{ "id": 2, "firstName": "Yeh", "lastName": "Dobedo", "title": "Mr", "birthDate": "1983-09-18", "address": "[{\"line1\":\"15 Book Street\",\"line2\":\"21 Book Street\"}]", "search_Permission": true }
方案二:后端修改模型适配嵌套JSON
如果希望客户端直接传递嵌套JSON结构(无需手动转义为字符串),可通过以下两种方式修改Director模型:
方式1:使用JsonElement类型
将address字段定义为JsonElement,可直接接收任意JSON结构,后续需要时再序列化为字符串存储:
public class Director { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Title { get; set; } public DateTime BirthDate { get; set; } public JsonElement Address { get; set; } // 修改为JsonElement类型 public bool Search_Permission { get; set; } }
控制器中转换为字符串的代码示例:
public async Task<ActionResult> PutDirector([FromBody] Director director, CancellationToken cancellationToken) { var title = nameof(PutDirector); // 将JsonElement转换为JSON字符串 string addressJson = director.Address.GetRawText(); // 后续业务逻辑处理 }
方式2:自定义JSON转换器
若需保持address为string类型,可添加自定义转换器,自动将嵌套JSON结构序列化为字符串:
- 创建转换器类:
public class JsonToStringConverter : JsonConverter<string> { public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 若读取到JSON对象或数组,转为字符串返回 if (reader.TokenType is JsonTokenType.StartObject or JsonTokenType.StartArray) { using var document = JsonDocument.ParseValue(ref reader); return document.RootElement.GetRawText(); } // 否则直接返回字符串 return reader.GetString() ?? string.Empty; } public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) { // 尝试解析字符串为JSON,成功则直接写入,否则写入原字符串 if (JsonDocument.TryParse(value, out var document)) { document.RootElement.WriteTo(writer); } else { writer.WriteStringValue(value); } } }
- 在
Director模型的Address字段上标记转换器:
public class Director { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Title { get; set; } public DateTime BirthDate { get; set; } [JsonConverter(typeof(JsonToStringConverter))] public string Address { get; set; } public bool Search_Permission { get; set; } }
此时客户端可直接传递嵌套JSON结构,无需手动转义:
{ "id": 2, "firstName": "Yeh", "lastName": "Dobedo", "title": "Mr", "birthDate": "1983-09-18", "address": [ { "line1": "15 Book Street", "line2": "21 Book Street" } ], "search_Permission": true }
控制器接收到的director.Address会自动转为JSON字符串:"[{\"line1\":\"15 Book Street\",\"line2\":\"21 Book Street\"}]"
内容的提问来源于stack exchange,提问作者ZedZip
相关产品推荐
相关产品推荐

