I have the following JSON:
{
"id" : "2"
"categoryId" : "35"
"type" : "item"
"name" : "hamburger"
}
{
"id" : "35"
"type" : "category"
"name" : "drinks"
}
And I want to match it to this object:
public class Item
{
[JsonProperty(PropertyName = "categoryId")]
public Category Category { get; set; }
}
Category
is of type Entity
which has a string
Id
property I can access. I want the "35" object created by the JSON Deserializer to be mapped to the Category
property in the Item
.
According to the documentation, I should use a IReferenceResolver
. How would I implement this interface and hook it into the JSON.NET framework?
SerializeObject Method (Object, Type, JsonSerializerSettings) Serializes the specified object to a JSON string using a type, formatting and JsonSerializerSettings. Namespace: Newtonsoft.Json.
You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored. If no Condition is specified, this option is assumed.
Specifies the settings on a JsonSerializer object. Newtonsoft.Json.
Provides methods for converting between . NET types and JSON types.
Use CustomCreationConverter<T>
as JsonConverter and override both Create
and ReadJson
method.
class ItemConverter : CustomCreationConverter<Item> {
public override Item Create(Type objectType)
{
return new Item();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
int categoryId = jObject["categoryId"].ToObject<int>();
Category category = Program.Repository.GetCategoryById(categoryId);
Item result = (Item)base.ReadJson(jObject.CreateReader(), objectType, existingValue, serializer);
result.Category = category;
return result;
}
}
class Item {
[JsonProperty("itemName")]
public string ItemName { get; set; }
public Category Category { get; set; }
// other properties.
}
class Category {
public int CategoryId { get; set; }
public string Name { get; set; }
// other properties.
}
class MockCategoryRepository {
IList<Category> _repository;
public MockCategoryRepository()
{
_repository = new List<Category>();
_repository.Add(new Category() { CategoryId = 1, Name = "Drink" });
_repository.Add(new Category() { CategoryId = 35, Name = "Food" });
_repository.Add(new Category() { CategoryId = 70, Name = "Fruit" });
}
public Category GetCategoryById(int id)
{
return _repository.Where(x => x.CategoryId == id).SingleOrDefault();
}
}
class Program {
public static MockCategoryRepository Repository { get; private set; }
static void Main(string[] args)
{
Repository = new MockCategoryRepository(); // initialize mock repository
// sample : json contains two items in an array.
string jsonString = @"
[
{ ""categoryId"":""35"", ""itemName"":""Item A"" },
{ ""categoryId"":""70"", ""itemName"":""Item B"" },
]";
List<Item> items = JsonConvert.DeserializeObject<List<Item>>(jsonString, new ItemConverter());
}
}
Solution for condition where Category
object information is fetched from the same json string.
class ItemConverter : CustomCreationConverter<Item> {
readonly IEnumerable<Category> _repository;
public ItemConverter(IEnumerable<Category> categories)
{
_repository = categories;
}
public override Item Create(Type objectType)
{
return new Item();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
int categoryId = jObject["categoryId"].ToObject<int>();
Category category = _repository.Where(x => x.CategoryId == categoryId).SingleOrDefault();
Item result = (Item)base.ReadJson(jObject.CreateReader(), objectType, existingValue, serializer);
result.Category = category;
return result;
}
}
class Item {
[JsonProperty("name")]
public string Name { get; set; }
public Category Category { get; set; }
// other properties.
}
class Category {
[JsonProperty("id")]
public int CategoryId { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
// other properties.
}
class Program {
static void Main(string[] args)
{
// sample : json contains items and/or categories in an array.
string jsonString = @"
[
{
""id"" : ""2"",
""categoryId"" : ""35"",
""type"" : ""item"",
""name"" : ""hamburger""
},
{
""id"" : ""35"",
""type"" : ""category"",
""name"" : ""drinks""
}
]";
JArray jsonArray = JArray.Parse(jsonString);
// Separate between category and item data.
IEnumerable<JToken> jsonCategories = jsonArray.Where(x => x["type"].ToObject<string>() == "category");
IEnumerable<JToken> jsonItems = jsonArray.Where(x => x["type"].ToObject<string>() == "item");
// Create list of category from jsonCategories.
IEnumerable<Category> categories = jsonCategories.Select(x => x.ToObject<Category>());
// Settings for jsonItems deserialization.
JsonSerializerSettings itemDeserializerSettings = new JsonSerializerSettings();
itemDeserializerSettings.Converters.Add(new ItemConverter(categories));
JsonSerializer itemDeserializer = JsonSerializer.Create(itemDeserializerSettings);
// Create list of item from jsonItems.
IEnumerable<Item> items = jsonItems.Select(x => x.ToObject<Item>(itemDeserializer));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With