處理同一屬性具有混合單值和數組值的 JSON 數據
問題:
處理 JSON 數據時,經常會遇到同一屬性既可以表示為單個值,也可以表示為值數組的情況。例如,考慮從 SendGrid API 獲取的以下有效負載:
[ { "email": "[email protected]", "timestamp": 1337966815, "category": [ "newuser", "transactional" ], "event": "open" }, { "email": "[email protected]", "timestamp": 1337966815, "category": "olduser", "event": "open" } ]
“category” 屬性說明了這個問題。對於某些項目,它是一個字符串,而對於其他項目,它是一個字符串數組。 JSON.NET 提供了兩種處理這種不一致性的方法:修改傳入的數據或配置 JSON.NET 以接受差異。
解決方案:自定義 JsonConverter
推薦的方法是使用自定義 JsonConverter。讓我們定義一個類來反序列化數據:
class Item { [JsonProperty("email")] public string Email { get; set; } [JsonProperty("timestamp")] public int Timestamp { get; set; } [JsonProperty("event")] public string Event { get; set; } [JsonProperty("category")] [JsonConverter(typeof(SingleOrArrayConverter<string>))] public List<string> Categories { get; set; } }
對於可能是單個項目或數組的屬性(在本例中為“category”),我們將其定義為 List
以下是轉換器的實現:
class SingleOrArrayConverter<T> : JsonConverter { public override bool CanConvert(Type objectType) { return (objectType == typeof(List<T>)); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JToken token = JToken.Load(reader); if (token.Type == JTokenType.Array) { return token.ToObject<List<T>>(); } if (token.Type == JTokenType.Null) { return null; } return new List<T> { token.ToObject<T>() }; } public override bool CanWrite { get { return false; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } }
此轉換器確定傳入的標記是數組還是單個項目,並相應地進行處理。如果它是數組,則將其轉換為 List
用法和輸出
要使用自定義轉換器,請按如下所示更新反序列化代碼:
string json = @"[ ... same as before ... ]"; List<Item> list = JsonConvert.DeserializeObject<List<Item>>(json);
程序將正確反序列化 JSON 數據,“category” 屬性將針對單個情況和數組情況適當地填充為字符串列表。
這種方法提供了一種靈活的方法來處理同一屬性具有混合值類型的 JSON 數據,無需修改數據或由於處理不一致而導致潛在的數據丟失。
以上是如何處理同一屬性的混合單和數組值的JSON數據?的詳細內容。更多資訊請關注PHP中文網其他相關文章!