使用 System.Text.Json 的自定义反序列化
Custom deserialization with System.Text.Json
我的项目中有一个 JSON 字符串,例如:(来自 API 调用)
(我也是先搜了一下,没有找到符合我情况的)
"
{
"property": [
{
"property_1": 1,
"property_2": true,
"property_3": [
{
"property_3_1": 11,
"property_3_2": "value_3_2_1",
"property_3_3": true
},
{
"property_3_1": 12,
"property_3_2": "value_3_2_2",
"property_3_3": false
}
]
},
{
"property_1": 2,
"property_2": false,
"property_3": [
{
"property_3_1": 21,
"property_3_2": "value_3_2_2",
"property_3_3": false
},
{
"property_3_1": 22,
"property_3_2": "value_3_2_2",
"property_3_3": true
}
]
}
]
}
"
我需要将其反序列化为下面的列表 class:
public class PropertyDto
{
public long Property_1 { get; set; }
public bool property_2 { get; set; }
public string property_3 { get; set; }
}
有没有办法将“property_3”数组反序列化为字符串?
类似于:
var peroperty = new PropertyDto();
peroperty.Peroperty_3 = "
[
{
"property_3_1": 21,
"property_3_2": "value_3_2",
"property_3_3": false
},
{
"property_3_1": 12,
"property_3_2": "value_3_2_2",
"property_3_3": false
}
]
"
Asp.Net核心5 | System.Text.Json
您可以通过以下方式实现此目的 JsonConverter
:
public class PropertyDtoConverter : JsonConverter<PropertyDto>
{
public override PropertyDto? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}
var dto = new PropertyDto();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return dto;
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
string propName = (reader.GetString() ?? "").ToLower();
reader.Read();
switch (propName)
{
case var _ when propName.Equals(nameof(PropertyDto.Property_1).ToLower()):
dto.Property_1 = reader.GetInt64();
break;
case var _ when propName.Equals(nameof(PropertyDto.Property_2).ToLower()):
dto.Property_2 = reader.GetBoolean();
break;
case var _ when propName.Equals(nameof(PropertyDto.Property_3).ToLower()):
if (JsonDocument.TryParseValue(ref reader, out JsonDocument jsonDoc))
{
dto.Property_3 = jsonDoc.RootElement.GetRawText();
}
break;
}
}
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, PropertyDto value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteNumber(nameof(PropertyDto.Property_1), value.Property_1);
writer.WriteBoolean(nameof(PropertyDto.Property_2), value.Property_2);
writer.WriteString(nameof(PropertyDto.Property_3), value.Property_3);
writer.WriteEndObject();
}
}
模型class将变为:
[JsonConverter(typeof(PropertyDtoConverter))]
public class PropertyDto
{
public long Property_1 { get; set; }
public bool Property_2 { get; set; }
public string Property_3 { get; set; }
}
您可以将字符串显式转换为 PropertyDto
:
PropertyDto dto = JsonSerializer.Deserialize<PropertyDto>(dtoString);
或隐含在控制器操作中:
[HttpPost]
public void Post(PropertyDto dto)
{
...
}
如果你想反序列化 PropertyDto
的整个集合,你可以这样做:
public class PropertyCollectionDto
{
public List<PropertyDto> Property { get; set; } = new();
}
[HttpPost("/collection")]
public void Post(PropertyCollectionDto dto)
{
...
}
我的项目中有一个 JSON 字符串,例如:(来自 API 调用) (我也是先搜了一下,没有找到符合我情况的)
"
{
"property": [
{
"property_1": 1,
"property_2": true,
"property_3": [
{
"property_3_1": 11,
"property_3_2": "value_3_2_1",
"property_3_3": true
},
{
"property_3_1": 12,
"property_3_2": "value_3_2_2",
"property_3_3": false
}
]
},
{
"property_1": 2,
"property_2": false,
"property_3": [
{
"property_3_1": 21,
"property_3_2": "value_3_2_2",
"property_3_3": false
},
{
"property_3_1": 22,
"property_3_2": "value_3_2_2",
"property_3_3": true
}
]
}
]
}
"
我需要将其反序列化为下面的列表 class:
public class PropertyDto
{
public long Property_1 { get; set; }
public bool property_2 { get; set; }
public string property_3 { get; set; }
}
有没有办法将“property_3”数组反序列化为字符串? 类似于:
var peroperty = new PropertyDto();
peroperty.Peroperty_3 = "
[
{
"property_3_1": 21,
"property_3_2": "value_3_2",
"property_3_3": false
},
{
"property_3_1": 12,
"property_3_2": "value_3_2_2",
"property_3_3": false
}
]
"
Asp.Net核心5 | System.Text.Json
您可以通过以下方式实现此目的 JsonConverter
:
public class PropertyDtoConverter : JsonConverter<PropertyDto>
{
public override PropertyDto? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}
var dto = new PropertyDto();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return dto;
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
string propName = (reader.GetString() ?? "").ToLower();
reader.Read();
switch (propName)
{
case var _ when propName.Equals(nameof(PropertyDto.Property_1).ToLower()):
dto.Property_1 = reader.GetInt64();
break;
case var _ when propName.Equals(nameof(PropertyDto.Property_2).ToLower()):
dto.Property_2 = reader.GetBoolean();
break;
case var _ when propName.Equals(nameof(PropertyDto.Property_3).ToLower()):
if (JsonDocument.TryParseValue(ref reader, out JsonDocument jsonDoc))
{
dto.Property_3 = jsonDoc.RootElement.GetRawText();
}
break;
}
}
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, PropertyDto value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteNumber(nameof(PropertyDto.Property_1), value.Property_1);
writer.WriteBoolean(nameof(PropertyDto.Property_2), value.Property_2);
writer.WriteString(nameof(PropertyDto.Property_3), value.Property_3);
writer.WriteEndObject();
}
}
模型class将变为:
[JsonConverter(typeof(PropertyDtoConverter))]
public class PropertyDto
{
public long Property_1 { get; set; }
public bool Property_2 { get; set; }
public string Property_3 { get; set; }
}
您可以将字符串显式转换为 PropertyDto
:
PropertyDto dto = JsonSerializer.Deserialize<PropertyDto>(dtoString);
或隐含在控制器操作中:
[HttpPost]
public void Post(PropertyDto dto)
{
...
}
如果你想反序列化 PropertyDto
的整个集合,你可以这样做:
public class PropertyCollectionDto
{
public List<PropertyDto> Property { get; set; } = new();
}
[HttpPost("/collection")]
public void Post(PropertyCollectionDto dto)
{
...
}