How to serialize property as though it was a base class? - c#

I have a object like this:
[JsonObject]
public class Thing<T> where T: class
{
[JsonProperty()]
T Data { get; set; }
[JsonProperty("error")]
public int ErrorCode { get; set; }
}
Is there a way to make it serialize it so that it would give something like this, when T is a class with a single value property for example:
{ value: "content", error: 1 }
instead of this:
{ data: { value: "content" }, error: 1 }
I sadly cannot derived from the data class.

You would need a custom converter for example:
[JsonConverter(typeof(HasValueConverter))]
public class HasValue
{
public HasValue(string value)
{
this.Value = value;
}
public string Value { get; set; }
}
[JsonObject]
public class Thing<T> where T: class
{
[JsonProperty("value")]
public T Data { get; set; }
[JsonProperty("error")]
public int ErrorCode { get; set; }
}
class HasValueConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(HasValue);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return new HasValue(JToken.Load(reader).Value<string>());
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
[Test]
public void Deserializes()
{
var json = "{ value: \"content\", error: 1 }";
var thing = JsonConvert.DeserializeObject<Thing<HasValue>>(json);
Assert.AreEqual("content", thing.Data.Value);
}

Related

Deserialize an abstract class that has only a getter using Newtonsoft

I'm trying to deseralize JSON I'm getting:
[
{
"Name":"0",
"Health":0,
"TypeName":"SpellInfo",
"Info":{
"Effect":1,
"EffectAmount":4
}
},
{
"Name":"1",
"Health":0,
"TypeName":"MonsterInfo",
"Info":{
"Health":10,
"AttackDamage":10
}
},
...
...
]
Created a class to handle the JSON:
[System.Serializable]
public class CardDataStructure
{
public string Name;
public int Health;
public string TypeName;
public Info Info;
}
I managed to get all the info I needed but the Info. From the research I did, I created a JsonConverter from a link - https://blog.codeinside.eu/2015/03/30/json-dotnet-deserialize-to-abstract-class-or-interface/
Which is actually pretty close,
public class InfoConvert: JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Info));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
if (jo.ToString().Contains("Effect"))
{
if (jo["Effect"].Value<string>() is string)
return jo.ToObject<SpellInfo>(serializer);
}
if (jo.ToString().Contains("Health"))
{
if (jo["Health"].Value<string>() is string)
return jo.ToObject<MonsterInfo>(serializer);
}
return null;
}
}
(It would have been better to find it by 'typename' but I couldn't figure out how to do that, so went with something simple)
When checking 'jo', the properties are there and go to the correct class yet once out of the converter I get default properties and not the once the converter showed.
I can't find the link but on the Newtonsoft doc it said somewhere there's a problem with deserializing an abstract class and if the abstract class doesn't have a public setter.
Both monsterinfo and spellinfo inherit from info:
[Serializable]
public abstract class Info
{
}
The monsterinfo and spellinfo look basically the same. Problem is they don't have a public setters and I cannot change them right now.
{
[Serializable]
public class MonsterInfo: Info
{
[SerializeField]
private int m_Health;
public int Health => m_Health;
[SerializeField]
private int m_AttackDamage;
public int AttackDamage => m_AttackDamage;
}
}
So, when trying to deseralize the JSON:
string contents = File.ReadAllText(source);
contents = "{\"cards\":" + contents + "}";
JsonConverter[] converters = { new InfoConvert() };
cardsData = JsonConvert.DeserializeObject<Cards>(contents, new JsonSerializerSettings() {
Converters = converters, NullValueHandling = NullValueHandling.Ignore,
TypeNameHandling = TypeNameHandling.Auto});
*Cards is a list of CardDataStructure
Is it even possible to get the data in Info without giving them a public setter?
Best I got is all the data inside the JSON and an empty Monster/Spell Info.
At the end I just need to parse the json I'm getting, but while the 'name', 'health', 'typeinfo' are parsed correctly, info is always an empty object filled with 0s.
Edit: Corrected some things.
You should do that like this dude:
A marker interface for detecting the type or deserializing
A container class
Dto classes
//marker interface
public interface Info { }
public class HealthInfo : Info
{
public int MoreHealth { set; get; }
public int AttackDamage { set; get; }
}
public class SpellInfo : Info
{
public int Effect { set; get; }
public int EffectAmount { set; get; }
}
public class Card<T> where T : Info
{
public Card(string name, int health, T info)
{
this.Info = info;
this.Name = name;
this.Health = health;
}
public T Info { private set; get; }
public string Name { set; get; }
public int Health { set; get; }
}
public class InfoConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
if (objectType == typeof(Card<Info>))
{
return true;
}
return false;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
if (jObject.ContainsKey("TypeName"))
{
string typeName = jObject["TypeName"]?.ToString()?.Trim()?.ToLower();
if (typeName?.Equals("monsterinfo") == true)
{
Card<HealthInfo> deseerialized = jObject.ToObject<Card<HealthInfo>>();
return new Card<Info>(deseerialized.Name, deseerialized.Health, deseerialized.Info);
}
if (typeName?.Equals("spellinfo") == true)
{
string json = jObject.ToString();
Card<SpellInfo> deseerialized = jObject.ToObject<Card<SpellInfo>>();
return new Card<Info>(deseerialized.Name, deseerialized.Health, deseerialized.Info);
}
}
return null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
And you should execute:
List<Card<Info>> list = JsonConvert.DeserializeObject<List<Card<Info>>>(jsonText, new InfoConverter());

How to model JSON with named properties on a common type

Here's sample JSON:
{
"notifications": [
{
"Profile.Guestbook.Post": {
"TargetIntId": 1,
"Digest": true,
"DigestSchedule": "00 * * * * *"
},
"Profile.MediaEntry.Post": {
"TargetIntId": 1,
"Digest": true,
"DigestSchedule": "00 * * * * *"
}
}
]
}
I'm trying to serialize into C# classes, where the NotificationInfo instance's EventName is the value of the keys, event.namespace1 and event2.namespaceX
public class Preferences
{
public List<NotificationInfo> Notifications { get;set; }
}
public class NotificationInfo
{
public string EventName { get;set; }
public int TargetIntId { get;set; }
public bool Digest { get;set; }
}
I created a dotnetfiddle: https://dotnetfiddle.net/8oqniT
The easiest way to get things working is to change your model to the following:
public class Preferences
{
public List<Dictionary<string, NotificationInfo>> Notifications { get; set; }
}
public class NotificationInfo
{
public int TargetIntId { get; set; }
public bool Digest { get; set; }
}
The event names from the JSON will be become the keys of the dictionary in the list.
Fiddle: https://dotnetfiddle.net/P3yD3p
However, this model can be a little bit awkward to use, as you can see from the fiddle. A better approach, in my opinion, is to keep your original model in place and use a custom JsonConverter to handle the translation. Here is the code you would need for the converter:
public class NotificationsConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(List<NotificationInfo>);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var array = JArray.Load(reader);
return array.Children<JObject>()
.SelectMany(jo => jo.Properties())
.Select(jp => new NotificationInfo
{
EventName = jp.Name,
TargetIntId = (int)jp.Value["TargetIntId"],
Digest = (bool)jp.Value["Digest"]
})
.ToList();
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
To use it, just add a [JsonConverter] attribute to your Notifications property like this:
[JsonConverter(typeof(NotificationsConverter))]
public List<NotificationInfo> Notifications { get; set; }
Fiddle: https://dotnetfiddle.net/vkjXC0

Where is the flaw in my attempt to implement a JsonConverter that handles interfaces and abstract classes?

I am trying to create an implementation of JsonConverter that can deserialize interfaces and abstract classes by using the first derived type that can be deserialized through default deserialization. Here is my unit test to give you can idea:
[TestMethod]
public void BaseTypeConverterCanConvertPolymorphicClass()
{
var polymorphicClass = new ConcreteFoo()
{
SomeString = "test string",
Bar = new ConcreteBar()
{
SomeInt = 18237
}
};
string serialized = JsonConvert.SerializeObject(polymorphicClass);
IFoo deserialized = JsonConvert.DeserializeObject<IFoo>(serialized);
Assert.IsTrue(deserialized is ConcreteFoo);
}
[JsonConverter(typeof(BaseTypeConverter))]
private interface IFoo
{
[JsonProperty("someString")]
string SomeString { get; }
[JsonProperty("bar")]
IBar Bar { get; }
}
private class ConcreteFoo : IFoo
{
public string SomeString { get; set; }
public IBar Bar { get; set; }
}
[JsonConverter(typeof(BaseTypeConverter))]
private interface IBar
{
[JsonProperty("someInt")]
int SomeInt { get; }
}
private class ConcreteBar : IBar
{
public int SomeInt { get; set; }
}
private class OtherConcreteBar : IBar
{
public int SomeInt { get; set; }
[JsonProperty("someDouble")]
public double SomeDouble { get; set; }
}
and here is my implementation:
public class BaseTypeConverter : JsonConverter
{
private static IDictionary<Type, ICollection<Type>> cache = new Dictionary<Type, ICollection<Type>>();
public override bool CanConvert(Type objectType)
{
return objectType.IsAbstract || objectType.IsInterface;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
IEnumerable<Type> derived = GetDerivedTypes(objectType);
var defaultSerializer = JsonSerializer.CreateDefault();
foreach (Type type in derived)
{
object deserialized = defaultSerializer.Deserialize(reader, type);
if (deserialized != null)
{
return deserialized;
}
}
throw new JsonException($"Could not deserialize type {objectType} into any of the dervied types: {string.Join(",", derived)}.");
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException($"Should never have to write because {nameof(CanWrite)} is {CanWrite}.");
}
private static IEnumerable<Type> GetDerivedTypes(Type baseType)
{
if (cache.ContainsKey(baseType))
{
return cache[baseType];
}
var derivedTypes =
(from domainAssembly in AppDomain.CurrentDomain.GetAssemblies()
from assemblyType in domainAssembly.GetTypes()
where baseType.IsAssignableFrom(assemblyType)
&& baseType != assemblyType
select assemblyType).ToList();
cache[baseType] = derivedTypes;
return derivedTypes;
}
}
The problem I'm finding is that somehow defaultSerializer.Deserialize(reader, type); is re-calling my ReadJson method rather than the "default" one like I expect. In other words, it calls it on type ConcreteFoo.
Where is the flaw in my logic?

JSON.Net Deseralize json pair to Object Propery

Ok I have WebApi application that is sending back name value pairs like so
{'FirstName':'SomeGuy'}
On the server the FirstName field is not just a string, it is a generic object that hold additional information about FirstName, and is not send back from the client.
Here is a outline of the classes
public abstract class Field
{
protected object _value;
......More Properties/Methods
public bool HasValue
{
get { return _hasValue; }
}
public object Value
{
get { return _hasValue ? _value : null; }
}
protected void SetValue(object value, bool clearHasValue = false)
{
_value = value;
_hasValue = clearHasValue ?
false :
value != null;
}
}
public class Field<T> : Field
{
..Constructors and methods
public new T Value
{
get { return _hasValue ? (T)_value : default(T); }
set { SetValue(value); }
}
}
So.. In theory I may be trying to bind to a model like
class FieldModel
{
public Field<string> FirstName { get; set; }
public Field<string> LastName { get; set; }
public Field<Decimal> Amount { get; set; }
public FieldModel()
{
FirstName = new Field<string>();
LastName = new Field<string>();
Amount = new Field<decimal>();
}
}
So here is the issue.. I want FirstName in my json object to deseralize to right property. Now if I modify the json package to {'FirstName.Value':'SomeGuy'} JSON.net works out of the box, but I really not to do that. I have been tying to make my own JsonConverter but have not been able to get that to work. So, I don't think this should be very hard, but I am a bit stuck.
EDIT
So.. I did come up with a solution that works, but I have to think there is a better way.. It uses dynamics and I have to think that I am missing an easy solution.
public class FieldConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
var internalVal = serializer.Deserialize(reader, objectType.GetGenericArguments().FirstOrDefault());
var retVal = existingValue as dynamic;
retVal.Value = internalVal as dynamic;
return retVal;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return objectType.IsSubclassOf(typeof(Field));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
You can easily do this with JSON.NET's CustomCreationConverter. Here's an example:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
}
public class Employee : Person
{
public string Department { get; set; }
public string JobTitle { get; set; }
}
public class PersonConverter : CustomCreationConverter<Person>
{
public override Person Create(Type objectType)
{
return new Employee();
}
}
And the usage:
string json = #"{
'Department': 'Furniture',
'JobTitle': 'Carpenter',
'FirstName': 'John',
'LastName': 'Joinery',
'BirthDate': '1983-02-02T00:00:00'
}";
Person person = JsonConvert.DeserializeObject<Person>(json, new PersonConverter());
Console.WriteLine(person.GetType().Name);
// Employee
Employee employee = (Employee)person;
Console.WriteLine(employee.JobTitle);
// Carpenter

Deserializing JSON to abstract class

I am trying to deserialize a JSON string to a concrete class, which inherits from an abstract class, but I just can't get it working. I have googled and tried some solutions but they don't seem to work either.
This is what I have now:
abstract class AbstractClass { }
class ConcreteClass { }
public AbstractClass Decode(string jsonString)
{
JsonSerializerSettings jss = new JsonSerializerSettings();
jss.TypeNameHandling = TypeNameHandling.All;
return (AbstractClass)JsonConvert.DeserializeObject(jsonString, null, jss);
}
However, if I try to cast the resulting object, it just doesn't work.
The reason why I don't use DeserializeObject is that I have many concrete classes.
Any suggestions?
I am using Newtonsoft.Json
One may not want to use TypeNameHandling (because one wants more compact json or wants to use a specific name for the type variable other than "$type"). Meanwhile, the customCreationConverter approach will not work if one wants to deserialize the base class into any of multiple derived classes without knowing which one to use in advance.
An alternative is to use an int or other type in the base class and define a JsonConverter.
[JsonConverter(typeof(BaseConverter))]
abstract class Base
{
public int ObjType { get; set; }
public int Id { get; set; }
}
class DerivedType1 : Base
{
public string Foo { get; set; }
}
class DerivedType2 : Base
{
public string Bar { get; set; }
}
The JsonConverter for the base class can then deserialize the object based on its type. The complication is that to avoid a stack overflow (where the JsonConverter repeatedly calls itself), a custom contract resolver must be used during this deserialization.
public class BaseSpecifiedConcreteClassConverter : DefaultContractResolver
{
protected override JsonConverter ResolveContractConverter(Type objectType)
{
if (typeof(Base).IsAssignableFrom(objectType) && !objectType.IsAbstract)
return null; // pretend TableSortRuleConvert is not specified (thus avoiding a stack overflow)
return base.ResolveContractConverter(objectType);
}
}
public class BaseConverter : JsonConverter
{
static JsonSerializerSettings SpecifiedSubclassConversion = new JsonSerializerSettings() { ContractResolver = new BaseSpecifiedConcreteClassConverter() };
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Base));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
switch (jo["ObjType"].Value<int>())
{
case 1:
return JsonConvert.DeserializeObject<DerivedType1>(jo.ToString(), SpecifiedSubclassConversion);
case 2:
return JsonConvert.DeserializeObject<DerivedType2>(jo.ToString(), SpecifiedSubclassConversion);
default:
throw new Exception();
}
throw new NotImplementedException();
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException(); // won't be called because CanWrite returns false
}
}
That's it. Now you can use serialize/deserialize any derived class. You can also use the base class in other classes and serialize/deserialize those without any additional work:
class Holder
{
public List<Base> Objects { get; set; }
}
string json = #"
[
{
""Objects"" :
[
{ ""ObjType"": 1, ""Id"" : 1, ""Foo"" : ""One"" },
{ ""ObjType"": 1, ""Id"" : 2, ""Foo"" : ""Two"" },
]
},
{
""Objects"" :
[
{ ""ObjType"": 2, ""Id"" : 3, ""Bar"" : ""Three"" },
{ ""ObjType"": 2, ""Id"" : 4, ""Bar"" : ""Four"" },
]
},
]";
List<Holder> list = JsonConvert.DeserializeObject<List<Holder>>(json);
string serializedAgain = JsonConvert.SerializeObject(list);
Debug.WriteLine(serializedAgain);
I would suggest to use CustomCreationConverter in the following way:
public enum ClassDiscriminatorEnum
{
ChildClass1,
ChildClass2
}
public abstract class BaseClass
{
public abstract ClassDiscriminatorEnum Type { get; }
}
public class Child1 : BaseClass
{
public override ClassDiscriminatorEnum Type => ClassDiscriminatorEnum.ChildClass1;
public int ExtraProperty1 { get; set; }
}
public class Child2 : BaseClass
{
public override ClassDiscriminatorEnum Type => ClassDiscriminatorEnum.ChildClass2;
}
public class BaseClassConverter : CustomCreationConverter<BaseClass>
{
private ClassDiscriminatorEnum _currentObjectType;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jobj = JObject.ReadFrom(reader);
_currentObjectType = jobj["Type"].ToObject<ClassDiscriminatorEnum>();
return base.ReadJson(jobj.CreateReader(), objectType, existingValue, serializer);
}
public override BaseClass Create(Type objectType)
{
switch (_currentObjectType)
{
case ClassDiscriminatorEnum.ChildClass1:
return new Child1();
case ClassDiscriminatorEnum.ChildClass2:
return new Child2();
default:
throw new NotImplementedException();
}
}
}
try something like this
public AbstractClass Decode(string jsonString)
{
var jss = new JavaScriptSerializer();
return jss.Deserialize<ConcreteClass>(jsonString);
}
UPDATE
for this scenario methinks all work as you want
public abstract class Base
{
public abstract int GetInt();
}
public class Der:Base
{
int g = 5;
public override int GetInt()
{
return g+2;
}
}
public class Der2 : Base
{
int i = 10;
public override int GetInt()
{
return i+17;
}
}
....
var jset = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };
Base b = new Der()
string json = JsonConvert.SerializeObject(b, jset);
....
Base c = (Base)JsonConvert.DeserializeObject(json, jset);
where c type is test.Base {test.Der}
UPDATE
#Gusman suggest use TypeNameHandling.Objects instead of TypeNameHandling.All. It is enough and it will produce a less verbose serialization.
Actually, as it has been stated in an update, the simplest way (in 2019) is to use a simple custom pre-defined JsonSerializerSettings, as explained here
string jsonTypeNameAll = JsonConvert.SerializeObject(priceModels, Formatting.Indented,new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
And for deserializing :
TDSPriceModels models = JsonConvert.DeserializeObject<TDSPriceModels>(File.ReadAllText(jsonPath), new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
public class CustomConverter : JsonConverter
{
private static readonly JsonSerializer Serializer = new JsonSerializer();
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jObject = JObject.Load(reader);
var typeString = jObject.Value<string>("Kind"); //Kind is a property in json , from which we know type of child classes
var requiredType = RecoverType(typeString);
return Serializer.Deserialize(jObject.CreateReader(), requiredType);
}
private Type RecoverType(string typeString)
{
if (typeString.Equals(type of child class1, StringComparison.OrdinalIgnoreCase))
return typeof(childclass1);
if (typeString.Equals(type of child class2, StringComparison.OrdinalIgnoreCase))
return typeof(childclass2);
throw new ArgumentException("Unrecognized type");
}
public override bool CanConvert(Type objectType)
{
return typeof(Base class).IsAssignableFrom(objectType) || typeof((Base class) == objectType;
}
public override bool CanWrite { get { return false; } }
}
Now add this converter in JsonSerializerSettings as below
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
jsonSerializerSettings.Converters.Add(new CustomConverter());
After adding serialize or deserialize base class object as below
JsonConvert.DeserializeObject<Type>("json string", jsonSerializerSettings );
I had a similar issue, and I solved it with another way, maybe this would help someone:
I have json that contains in it several fields that are always the same, except for one field called "data" that can be a different type of class every time.
I would like to de-serialize it without analayzing every filed specific.
My solution is:
To define the main class (with 'Data' field) with , the field Data is type T.
Whenever that I de-serialize, I specify the type:
MainClass:
public class MainClass<T>
{
[JsonProperty("status")]
public Statuses Status { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("data")]
public T Data { get; set; }
public static MainClass<T> Parse(string mainClsTxt)
{
var response = JsonConvert.DeserializeObject<MainClass<T>>(mainClsTxt);
return response;
}
}
User
public class User
{
[JsonProperty("id")]
public int UserId { get; set; }
[JsonProperty("first_name")]
public string FirstName { get; set; }
[JsonProperty("last_name")]
public string LastName { get; set; }
}
Product
public class Product
{
[JsonProperty("product_id")]
public int ProductId { get; set; }
[JsonProperty("product_name")]
public string ProductName { get; set; }
[JsonProperty("stock")]
public int Stock { get; set; }
}
Using
var v = MainClass<User>.Parse(userJson);
var v2 = MainClass<Product>.Parse(productJson);
json example
userJson: "{"status":1,"description":"my description","data":{"id":12161347,"first_name":"my fname","last_name":"my lname"}}"
productJson: "{"status":1,"description":"my description","data":{"product_id":5,"product_name":"my product","stock":1000}}"
public abstract class JsonCreationConverter<T> : JsonConverter
{
protected abstract T Create(Type objectType, JObject jObject);
public override bool CanConvert(Type objectType)
{
return typeof(T) == objectType;
}
public override object ReadJson(JsonReader reader,Type objectType,
object existingValue, JsonSerializer serializer)
{
try
{
var jObject = JObject.Load(reader);
var target = Create(objectType, jObject);
serializer.Populate(jObject.CreateReader(), target);
return target;
}
catch (JsonReaderException)
{
return null;
}
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Now implement this interface
public class SportActivityConverter : JsonCreationConverter<BaseSportActivity>
{
protected override BaseSportActivity Create(Type objectType, JObject jObject)
{
BaseSportActivity result = null;
try
{
switch ((ESportActivityType)jObject["activityType"].Value<int>())
{
case ESportActivityType.Football:
result = jObject.ToObject<FootballActivity>();
break;
case ESportActivityType.Basketball:
result = jObject.ToObject<BasketballActivity>();
break;
}
}
catch(Exception ex)
{
Debug.WriteLine(ex);
}
return result;
}
}

Categories

Resources