我有两个 JSON 文件:一个用于位置,另一个用于某个位置的对象。
locations.json =>
[
{
"Name": "Location#1",
"X": 0,
"Y": 20
},
{
"Name": "Location#2",
"X": 0,
"Y": 19
},
...
]
objects.json ==>
[
{
"Name": "Piano",
"CurrentLocation": "Location#1"
},
{
"Name": "Violin",
"CurrentLocation": "Location#2"
},
...
]
objects.json 使用位置名称引用位置实例。
我有两个类,可以反序列化到(或从中序列化):
public class ObjectOfInterest
{
[JsonPropertyName("Name")]
public string Name { get; set; } = string.Empty;
[JsonPropertyName("CurrentLocation")]
public LocationNode CurrentLocation { get; set; } = new()
}
public class Location
{
[JsonPropertyName("Name")]
public string Name { get; set; } = string.Empty;
[JsonPropertyName("X")]
public float X { get; set; }
[JsonPropertyName("Y")]
public float Y { get; set; }
}
如何创建采用字符串位置名称 JSON 属性的自定义 JSONSerializer 或转换器,并将正确的位置实例分配给 Objects 类?
将 JsonConverterAttribute 添加到 CurrentLocation 属性
public class ObjectOfInterest
{
[JsonPropertyName("Name")]
public string Name { get; set; } = string.Empty;
[JsonPropertyName("CurrentLocation")]
[JsonConverter(typeof(LocationConverter))]
public Location CurrentLocation { get; set; } = new();
}
转换器应存储按其名称索引的位置:
public class LocationConverter : JsonConverter<Location>
{
private readonly Dictionary<string, Location> _locationDictionary = new();
public LocationConverter(IEnumerable<Location> locations)
{
foreach (var location in locations)
{
_locationDictionary[location.Name] = location;
}
}
public override Location Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string locationName = reader.GetString();
if (_locationDictionary.TryGetValue(locationName, out Location location))
{
return location;
}
throw new KeyNotFoundException($"Location '{locationName}' not found.");
}
public override void Write(Utf8JsonWriter writer, Location value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.Name);
}
}
最后,您可以像这样使用 LocationConverter:
var List<Location> locations = JsonSerializer.Deserialize<Location[]>(locationsJson);
var options = new JsonSerializerOptions
{
Converters = new[]{ new LocationConverter(locations) }
};
var objects = JsonSerializer.Deserialize<ObjectOfInterest[]>(objectsJson, options);