在 c# 中从引用 ID 反序列化 JSON 对象



我有一个 json 中的项目列表

"items":[
{
"id": 0,
"name": "Thats a name",
"type": 0,
"price": 3.5,
"ingredients": [1,0,2,3],
},
{
"id": 1,
"name": "This is AnotherName",
"type": 0,
"price": 3.7,
"ingredients": [5,0,6,10,2,8],
}
]

typeingredients属性在同一 JSON 文件的另一个对象中详细介绍。如果我查一下,我知道0型是什么,成分是什么。

在 c# 中,我试图实现的是让我的数据模型不是到处都有int,而是有实际的对象。例如,对于成分,我的Item对象具有类型List<Ingredient>而不是List<int>Ingredients属性。

像下面这样:

public IEnumerable<Ingredient> Ingredients { get; set; }
public IEnumerable<FoodType> Types { get; set; }
public IEnumerable<FoodItem> Items { get; set; }

public class FoodItem
{
public int Id { get; set; }
public string Name { get; set; }
public int Type { get; set; }
public float Price { get; set; }
public IEnumerable<Ingredient> Ingredients { get; set; }
}

但是在我的反序列化的当前状态下,它崩溃了,因为它正在寻找一个 int。

我找到了关于"PreserveReferenceHandling"或"isReference"的关键字,但没有真正的帮助,但我不确定这些是什么,甚至不知道如何使用它们。

这就是我反序列化的方式:

var json = r.ReadToEnd();
var items = JsonConvert.DeserializeObject<EatupDataModel>(json);

我知道以下内容会起作用:

  • 更改 json 文件以包含实际对象而不是 ID
  • 将数据模型更改为使用int而不是对象

但我非常不想那样做,第一个需要大量繁琐的工作,另一个迫使我拥有几乎相同对象的 2 个版本,然后映射两者之间的属性。这似乎很愚蠢,我当然不能成为第一个面对这种情况的人。

我能做些什么来实现我的目标?

You will want to clean this up a bit. But should give you a proof of concept on how to do create your custom converter.
public class Item
{
public int id { get; set; }
public string name { get; set; }
public int type { get; set; }
public double price { get; set; }
[JsonConverter(typeof(KeysJsonConverter))]
public List<Ingredient> ingredients { get; set; }
}
public class RootObject
{
public List<Item> items { get; set; }
}
public class KeysJsonConverter : JsonConverter
{      
public KeysJsonConverter()
{
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanWrite is false. The type will skip the converter.");
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var ingredientsList = new List<Ingredient>();
if (reader.TokenType != JsonToken.Null)
{
if (reader.TokenType == JsonToken.StartArray)
{
JToken token = JToken.Load(reader);
List<int> items = token.ToObject<List<int>>();
ingredientsList = items.Select(x => IngredientList.Ingredients.FirstOrDefault(y => y.Id == x)).ToList();
}
}
return ingredientsList;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(object[]);
}
}
public static class IngredientList
{
public static List<Ingredient> Ingredients = new List<Ingredient>()
{
new Ingredient()
{
Id = 1,
Name = "Test 1"
},
new Ingredient()
{
Id = 2,
Name = "Test 2"
}
};
}
public class Ingredient{
public string Name { get; set; }
public int Id { get; set; }
}

最新更新