Modify/Add property via custom IContractResolver - c#

I have a class:
public class MyClass
{
public MyEnum Foo{ get; set; }
}
During serialization i'd like to change the output from
{
"Foo": 1
}
to
{
"Foo": "EnumName"
}
I've tried creating an IValueProvider but hit dead ends every way I go. (My scenario is a bit more complicated than stated; I need to find a way to do this entirely within the IContractResolver.)

You could create a custom ContractResolver inheriting from DefaultContractResolver that automatically applies StringEnumConverter to every contract for an enum or nullable enum:
public class StringEnumContractResolver : DefaultContractResolver
{
readonly StringEnumConverter converter;
public StringEnumContractResolver() : this(true, false) { }
public StringEnumContractResolver(bool allowIntegerValue, bool camelCaseText)
{
this.converter = new StringEnumConverter { AllowIntegerValues = allowIntegerValue, CamelCaseText = camelCaseText };
}
protected override JsonPrimitiveContract CreatePrimitiveContract(Type objectType)
{
var contract = base.CreatePrimitiveContract(objectType);
var type = Nullable.GetUnderlyingType(contract.UnderlyingType) ?? contract.UnderlyingType;
if (type.IsEnum && contract.Converter == null)
contract.Converter = converter;
return contract;
}
}
Notes:
If the enum type already has a JsonConverter applied, that is kept in preference to the default StringEnumConverter.
Adding the converter to the JsonPrimitiveContract for the enum itself, rather than to every JsonProperty for members that return the enum, ensures that the converter is applied to enums in collections and dictionaries.
The IValueProvider merely provides methods to get and set values and thus is less convenient to this purpose than the converter. You would need to perform a nested serialization and deserialization of the enum value as a JSON string inside it, but it isn't designed for this and so doesn't have access to the JSON reader, writer, or serializer. In addition, there is no value provider for dictionary values or collection items that are enums.
You may want to cache the contract resolver for best performance as explained here.
Sample .Net fiddle.

Related

Ignore [DataMember(Name = "xx")] at json serialisation [duplicate]

We are running into a situation on an MVC3 project with both the Microsoft JSON serializers and JSON.NET.
Everybody knows DateTime's are basically broken in Microsoft's serializers, so we switched to JSON.NET to avoid this issue. That works great, except that some of the classes we are trying to serialize are POCOs with DataContract/DataMember attributes. They are defined in an assembly that is referenced in multiple places. Additionally, they have some other display properties that are not marked as DataMembers for efficiency. For instance, a Customer
[DataContract]
public class Customer
{
[DataMember]
public string FirstName { get; set;}
[DataMember]
public string LastName { get; set;}
public string FullName
{
get
{ return FirstName + " " + LastName; }
}
}
When this customer is passed over WCF the client side can reference that assembly and use the FullName just fine, but when serialized with JSON.NET it sees that FullName isn't a [DataMember] and doesn't serialize it. Is there an option to pass to JSON.NET to tell it to ignore the fact that a class has [DataContract] attribute applied?
Note:
Using the JavaScriptSerializer in .NET works fine for the FullName property, but DateTimes are broken. I need JSON.NET to ignore the fact that this class has DataContract/DataMember attributes and just do standard public field serialization like it would if they weren't there.
Simply use Json.Net's OptOut attribute. It will take precedence over DataContract.
[DataContract]
[JsonObject(MemberSerialization.OptOut)]
As Amry said you can uses your own IContractResolver.
Unfortunately the solution provided by Amry didn't work for me, below is the solution that I managed to get working:
public class AllPropertiesResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
//property.HasMemberAttribute = true;
property.Ignored = false;
//property.ShouldSerialize = instance =>
//{
// return true;
//};
return property;
}
}
There are a few lines commented, these wern't required to make my solution work, but you never know!
This has the same usage as Amry's solution:
var json = JsonConvert.SerializeObject(result, new JsonSerializerSettings {
ContractResolver = new AllPropertiesResolver()
});
Hope this helps!
I was having a problem almost related to what you're having, and managed to find a solution by going through Json.NET's codes. So it may not be the best solution, but it works for me.
To do this, you need to implement your own IContractResolver. An over-simplified implementation of that to include all parameters and ignores all attributes (not just DataContract but other built-in Json.NET's rules as well, so whatever options you set that should originally affect the members selection is now being overidden by this code):
class AllPropertiesResolver : DefaultContractResolver
{
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
return objectType.GetProperties()
.Where(p => p.GetIndexParameters().Length == 0)
.Cast<MemberInfo>()
.ToList();
}
}
And here comes the code usage example:
var json = JsonConvert.SerializeObject(result, new JsonSerializerSettings {
ContractResolver = new AllPropertiesResolver()
});
In accordance to the Json.NET documentation [DataMember] attributes are ignored if the properties are also annotated with Json.NET specific attributes (such as [JsonProperty]).See the Serialization Attributes documentation for details:
Json.NET attributes take presidence over standard .NET serialization attributes, e.g. if both JsonPropertyAttribute and DataMemberAttribute are present on a property and both customize the name, the name from JsonPropertyAttribute will be used.
The documentation only covers the name property, but for my experience the [JsonProperty] attribute also fully shadows settings done by the [DataMember] attribute. So, if it is feasible for your case, also add Json.NET attributes to the properties for which the [DataMember] annotation should be ignored.
If you want to ignore the presence of DataContractAttribute for all types without having to add additional attributes, then a custom contract resolver is the correct solution. However, as of Json.NET 9.0.1 Amry's resolver no longer works. Doolali's resolver works but it has the additional side effect of serializing all public properties including those marked with [JsonIgnore]. If you require a contract resolver that only ignores the presence of DataContractAttribute but otherwise behaves like the default contract resolver, the following can be used:
public class IgnoreDataContractContractResolver : DefaultContractResolver
{
static MemberSerialization RemoveDataContractAttributeMemberSerialization(Type type, MemberSerialization memberSerialization)
{
if (memberSerialization == MemberSerialization.OptIn)
{
type = Nullable.GetUnderlyingType(type) ?? type;
// Json.NET interprets DataContractAttribute as inherited despite the fact it is marked with Inherited = false
// https://json.codeplex.com/discussions/357850
// https://stackoverflow.com/questions/8555089/datacontract-and-inheritance
// https://github.com/JamesNK/Newtonsoft.Json/issues/603
// Thus we need to manually climb the type hierarchy to see if one is present.
var dataContractAttribute = type.BaseTypesAndSelf().Select(t => t.GetCustomAttribute<DataContractAttribute>()).FirstOrDefault(a => a != null);
var jsonObjectAttribute = type.GetCustomAttribute<JsonObjectAttribute>();
if (dataContractAttribute != null && jsonObjectAttribute == null)
memberSerialization = MemberSerialization.OptOut;
}
return memberSerialization;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var properties = base.CreateProperties(type, RemoveDataContractAttributeMemberSerialization(type, memberSerialization));
return properties;
}
protected override JsonObjectContract CreateObjectContract(Type objectType)
{
var contract = base.CreateObjectContract(objectType);
contract.MemberSerialization = RemoveDataContractAttributeMemberSerialization(objectType, contract.MemberSerialization);
return contract;
}
}
public static class TypeExtensions
{
public static IEnumerable<Type> BaseTypesAndSelf(this Type type)
{
while (type != null)
{
yield return type;
type = type.BaseType;
}
}
}
You may want to cache the contract resolver for best performance.
Have you tried this?
IgnoreDataMemberAttribute

Exclude an enum property of a Model from using the JsonStringEnumConverter which is globally set at the Startup?

I am developing the ASP.NET Core Application using the latest .NET Core 3.1.1 and System.Text.Json which was previously using the Newtonsoft.Json. As recommended in the Microsoft Migration guide
I have done the changes. Also, as most of my enums need to be serialized as String I have configured my Startup.cs ConfigureServices to use the JsonStringEnumConverter globally.
public void ConfigureServices(IServiceCollection services)
{
// lines omitted for brevity
services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
options.JsonSerializerOptions.IgnoreNullValues = true;
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});
}
But recently, after the release we realized that only a few enums are given out as numerals in json through our API. As these APIs are consumed externally, changing the numerals to strings might be a costly stuff.
So, is there a way to ignore the universal for some enum properties like the decoration with the [JsonIgnore] attribute?
JsonStringEnumConverter is actually a subclass of JsonConverterFactory. It manufactures a specific JsonConverterEnum for each concrete enum type encountered during serialization that, in turn, serializes that specific enum type as a string.
If you don't want some specific enum type to be serialized as a string, you can use the decorator pattern and create your own converter factory that decorates a JsonStringEnumConverter but prevents that enum type from being converted as follows:
public class OptOutJsonConverterFactory : JsonConverterFactoryDecorator
{
readonly HashSet<Type> optOutTypes;
public OptOutJsonConverterFactory(JsonConverterFactory innerFactory, params Type [] optOutTypes) : base(innerFactory) => this.optOutTypes = optOutTypes.ToHashSet();
public override bool CanConvert(Type typeToConvert) => base.CanConvert(typeToConvert) && !optOutTypes.Contains(typeToConvert);
}
public class JsonConverterFactoryDecorator : JsonConverterFactory
{
readonly JsonConverterFactory innerFactory;
public JsonConverterFactoryDecorator(JsonConverterFactory innerFactory)
{
if (innerFactory == null)
throw new ArgumentNullException(nameof(innerFactory));
this.innerFactory = innerFactory;
}
public override bool CanConvert(Type typeToConvert) => innerFactory.CanConvert(typeToConvert);
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => innerFactory.CreateConverter(typeToConvert, options);
}
Then use it in options as follows:
options.Converters.Add(new OptOutJsonConverterFactory(new JsonStringEnumConverter(),
// Add here all enum types to serialize as integers:
typeof(SomeEnumNotToSerializeAsAString)
//, ...
));
Notes:
If maintaining a list of enum types to serialize as integers is inconvenient, you could mark the enum types to be serialized as integers with some custom attribute, then exclude types marked with that attribute from within CanConvert(CanConvert(Type typeToConvert).
The decorator pattern is required because JsonStringEnumConverter is sealed.
Mockup fiddle #1 here.
Alternatively, if you don't want some specific enum property to be serialized as a string, you can apply a converter to the property using JsonConverterAttribute that ignores the incoming JsonSerializerOptions and generates a default serialization instead:
/// <summary>
/// Apply this converter to a property to force the property to be serialized with default options.
/// This converter can ONLY be applied to a property; setting it in options or on a type may cause a stack overflow exception!
/// </summary>
/// <typeparam name="T">the property's declared return type</typeparam>
public class SerializePropertyAsDefaultConverter<T> : JsonConverter<T>
{
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<T>(ref reader); // Ignore the incoming options!
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value); // Ignore the incoming options!
}
}
And apply it to your model as follows:
public class Model
{
public StringEnum StringEnum { get; set; }
[JsonConverter(typeof(SerializePropertyAsDefaultConverter<SomeEnumNotToSerializeAsAString>))]
public SomeEnumNotToSerializeAsAString SomeEnumNotToSerializeAsAString { get; set; }
}
Notes:
This solution takes advantage of the documented precedence for converters:
[JsonConverter] applied to a property.
A converter added to the Converters collection.
[JsonConverter] applied to a custom value type or POCO.
Mockup fiddle #2 here.

Conditional serialization/deserialization of object properties with json.net [duplicate]

This question already has answers here:
Serialize Property, but Do Not Deserialize Property in Json.Net
(2 answers)
Closed 6 years ago.
I have a scenario with a class defined as below:
class MyObject
{
public DataDictionary MyObjectData { get; set; }
public bool ShouldSerializeMyObjectData() { return true; }
public bool ShouldDeserializeMyObjectData() { return false; }
}
When I attempt to serialize/deserialize that class with JSON.net, it takes the ShouldSerialize into account, but not the ShouldDeserialize.
According to the documentation, both should work the same way I guess. Is there something particular I should know? More generally, how should I deal with scenarios where I want to serialize a property but not deserialize it?
I'm using Json.NET 8.0 if that matters.
Thanks for your help.
The short answer to your question is, automatically checking for ShouldDeserialize{PropertyName}() is not currently implemented even though ShouldSerialize{PropertyName}() is. A longer answer and workaround follow.
The class JsonProperty is used internally by Json.NET to define a contract for how to map a JSON property to a .NET member or constructor parameter. It has two predicate properties, ShouldSerialize and ShouldDeserialize that, when non-null, prevent a property from being serialized and deserialized, respectively. Initializing each JsonProperty is the job of the ContractResolver. For each property {PropertyName}, Json.NET's default contract resolver automatically checks for the presence of a public bool ShouldSerialize{PropertyName}() method. If such a method exists, it adds a call to it in the ShouldSerialize predicate, thereby suppressing serialization when the method returns false. This was implemented because controlling property serialization via a method ShouldSerialize{PropertyName}() is a standard pattern supported by, e.g., XmlSerializer. For more background see the relevant Json.NET release notes.
For example, in the following class, serialization of MyObjectData will be suppressed unless MyObjectData.Count > 0:
class MyObject
{
public DataDictionary MyObjectData { get; set; }
public bool ShouldSerializeMyObjectData() { return MyObjectData != null && MyObjectData.Count > 0; }
}
JsonProperty.ShouldDeserialize, however, it is never set by the default contract resolver. This may be due to the fact that there is no standard pattern for deserialization equivalent to ShouldSerialize{PropertyName}() and so Newtonsoft never had any requests to implement such a pattern. Nevertheless, as you have noticed, infrastructure to support such a pattern exists, and so applications can create custom contract resolvers that do just that. In fact, Json.NET has an example of such a contract resolver in its own test suite:
public class ShouldDeserializeContractResolver : DefaultContractResolver
{
public static new readonly ShouldDeserializeContractResolver Instance = new ShouldDeserializeContractResolver();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
MethodInfo shouldDeserializeMethodInfo = member.DeclaringType.GetMethod("ShouldDeserialize" + member.Name);
if (shouldDeserializeMethodInfo != null)
{
property.ShouldDeserialize = o => { return (bool)shouldDeserializeMethodInfo.Invoke(o, null); };
}
return property;
}
}
public class ShouldDeserializeTestClass
{
[JsonExtensionData]
public IDictionary<string, JToken> ExtensionData { get; set; }
public bool HasName { get; set; }
public string Name { get; set; }
public bool ShouldDeserializeName()
{
return HasName;
}
}
If you want to conditionally suppress deserialization of properties even when present in the JSON, you may use this contract resolver.
Notes:
If you do use a custom contract resolver, you should cache and reuse it for best performance.
JsonProperty.ShouldDeserialize is called before the property value is deserialized. If it returns true, the property is skipped, with no ability to examine the contents of the property. Thus it cannot be used to implement custom filtering based on that value.
A JSON object is defined by the JSON standard as an unordered set of name/value pairs. Thus a ShouldDeserialize method that assumes that other properties have already been read in may be brittle.
Instead, if you want to skip deserialization of one property based on the value of another, consider using an [OnDeserialized] callback and clearing the unwanted value there, after all properties have been deserialized.

NullValueHandling.Ignore influences deserialization into [ExtensionData] despite matching class member

My server responses consists of a set of known and unknown properties. For the known ones, I created a DTO class with members for each property. The unknown properties shall be put inside a dictionary annotated with the [ExtensionData] attribute:
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class Dto
{
[JsonExtensionData]
private readonly Dictionary<string, object> unknownProperties = new Dictionary<string, object>();
public IDictionary<string, object> UnknownProperties
{
get
{
return new ReadOnlyDictionary<string, object>(this.unknownProperties);
}
}
[JsonProperty(Required = Required.Default, PropertyName = "KNOWN_PROPERTY")]
public string KnownProperty { get; private set; }
}
Null is allowed as value for KnownProperty. If I try to deserialize a JSON object that contains KNOWN_PROPERTY : null, this property is also contained in the dictionary UnknownProperties, if I configure the serializer with NullValueHandling.Ignore. This is done even though a class member exists for KNOWN_PROPERTY:
static void Main(string[] args)
{
string jsonString = #"{
KNOWN_PROPERTY : null,
UNKNOWN_PROPERTY : null
}";
JsonSerializer serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore
});
using (var textReader = new StringReader(jsonString))
{
Dto dto = serializer.Deserialize<Dto>(new JsonTextReader(textReader));
foreach (var pair in dto.UnknownProperties)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value == null ? "null" : pair.Value.ToString());
}
}
}
Output:
KNOWN_PROPERTY : null
UNKNOWN_PROPERTY : null
If I configure the serializer with NullValueHandling.Include or set a value for KNOWN_PROPERTY in the JSON string, the dictionary contains only UNKNOWN_PROPERTY, as expected.
For my understanding [ExtensionData] is not working correctly if NullValueHandling is set to ignore, since the documentation states the extension is used only if no matching class member is found.
Is the behavior I'm seeing intended? Can I do something to avoid this? Because I don't like to send null values to the server, I'd like to stick to the currently set NullValueHandling.
I'm using Json.NET 8.0.2
Update
Reported in JsonExtensionData should not include the null values that are real object properties. #1719 and fixed in commit e079301. The fix should be included in the next release of Json.NET after 11.0.2.
Original Answer
Confirmed - in JsonSerializerInternalReader.PopulateObject(object, JsonReader, JsonObjectContract, JsonProperty, string) there is the following logic:
// set extension data if property is ignored or readonly
if (!SetPropertyValue(property, propertyConverter, contract, member, reader, newObject))
{
SetExtensionData(contract, member, reader, memberName, newObject);
}
The intent seems to be to put the value into the extension data if the property is to be ignored, but Json.NET puts it into the extension data if the value is to be ignored -- a slightly different concept. I agree this could be a bug. You might want to report it.
There is a workaround. Json.NET has two attributes that affect how null/default values are serialized:
NullValueHandling. Specifies to include or ignore null values when serializing and deserializing objects. Values are Include and Ignore.
DefaultValueHandling. This has more elaborate semantics:
Include: Include members where the member value is the same as the member's default value when serializing objects. Included members are written to JSON. Has no effect when deserializing.
Ignore: Ignore members where the member value is the same as the member's default value when serializing objects so that is is not written to JSON. This option will ignore all default values (e.g. null for objects and nullable types; 0 for integers, decimals and floating point numbers; and false for booleans).
Populate: Members with a default value but no JSON will be set to their default value when deserializing.
IgnoreAndPopulate: Ignore members where the member value is the same as the member's default value when serializing objects and sets members to their default value when deserializing.
So, how do these overlapping settings interact? It turns out that Json.NET checks them both: serialize if both settings are agreeable, deserialize if both settings are agreeable. And DefaultValueHandling.IgnoreAndPopulate appears to do what you want -- it omits nulls when serializing, but reads and sets them when deserializing, if present.
Thus I was able to get your desired behavior with the following JsonProperty:
public class Dto
{
[JsonProperty(Required = Required.Default, PropertyName = "KNOWN_PROPERTY", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate, NullValueHandling = NullValueHandling.Include)]
public string KnownProperty { get; private set; }
// Remainder as before.
}
Prototype fiddle.

JSON.NET: Deserialize a class containig a List of objects derived from an interface

I have troubles deserializing my object. It contains following property:
public List<IShape> Shapes { get; set; };
and JSON.NET deserializer always tells me, that it is not possible to instantiate an interface.
I have several classes which implement interfaces which implement IShape interface, e.g. Polyline -> IPolyline -> IShape. I tried two solutions already:
https://stackoverflow.com/a/8031283/1525505
https://stackoverflow.com/a/12769061/1525505
But I got the same exception, that IShape cannot be instantied, was thrown.
I serialize the object with TypeNameHandling.Auto, TypeNameHandling.All doesn't help too, even when I use the converters mentioned in posts I linked above.
Does anyone know of a solution to this problem? If some code is needed I will gladly post it.
Here is a sample of JSON that is generated.
"$type": "SketchModel.Layer, SketchModel",
"Id": 57865477,
"Shapes": {
"$type": "System.Collections.Generic.List`1[[SketchModel.Shapes.AbstractShapes.IShape, SketchModel]], mscorlib",
"$values": [
{
"$type": "SketchModel.Shapes.Polyline, SketchModel",
This line is responsible for the problem:
"System.Collections.Generic.List`1[[SketchModel.Shapes.AbstractShapes.IShape, SketchModel]], mscorlib"
It simply doesn't know how to instantiate IShape. If I create a custom converter and let it return a Polyline for each IShape, it works, but doesn't create any other shapes (e.g. Ellipses).
In the
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) method which is overriden in the custom converter, if I let me print the full type name of objectType it's always IShape, never anything else...
The exception makes sense because the deserializer doesn't know what concrete type the interface is supposed to represent when hydrating.
During serialization, JSON.NET allows you to configure it to add some meta data to be used in this case. This SO question has an answer explaining how to configure it.
The configuration will add a type property to the JSON that will be used during deserialization.
I had exactly this problem and only solved it by explicitly providing a converter for the Type. It doesn't work if I use annotations - I need to pass the converters in at deserialization - basically like this:
state = JsonConvert.DeserializeObject<StateImpl>((String)stateObject, new JsonConverter[] { new StatePersistenceStateEntryConverter(), new StatePersistenceUserInteractionConverter() });
Where my StateImpl object included these properties:
[DataMember]
[JsonProperty("stateEntries", TypeNameHandling = TypeNameHandling.Auto)]
public List<IStateEntry> StateEntries
{
get;
set;
}
[DataMember]
[JsonProperty("precommitStateEntry", TypeNameHandling = TypeNameHandling.Auto)]
public IPrecommitStateEntry PrecommitStateEntry
{
get;
set;
}
IPrecommitStateEntry extends the IStateEntry interface (just FYI in case you're wondering why the extra logic in the converter).
Also - in my IStateEntry object, I have a similar child problem:
[DataMember]
[JsonProperty("userInteractions", TypeNameHandling = TypeNameHandling.Auto)]
public List<IUserInteraction> UserInteractions
{
get;
set;
}
So my object has child list properties of IStateEntry and an IStateEntry has a further child list of IUserInteraction. My converters are as follows:
public class StatePersistenceStateEntryConverter : CustomCreationConverter<IStateEntry>
{
public override IStateEntry Create(Type objectType)
{
if (objectType == typeof(IPrecommitStateEntry))
{
return new PrecommitStateEntry();
}
else
{
return new StateEntry();
}
}
}
And...
public class StatePersistenceUserInteractionConverter : CustomCreationConverter<IUserInteraction>
{
public override IUserInteraction Create(Type objectType)
{
return new UserInteraction();
}
}
Literally all they're doing is creating an instance of that particular object implementation.
So I don't know why the converters are needed as clearly a List can be instantiated - just not the IStateEntry individually. Clearly there's a bug in the NewtonSoft implementation somewhere - or I'm missing something fundamental.
Hope that helps. It was a frustrating few hours for me, but now working!
Without including concrete types within your Json string, you can use a JsonConverter to convert an IList<SomeInterface> to their concrete type:
Class to deserialize:
public partial class MovieInfo : IMovieInfo
{
~~~~
[JsonProperty("genres")]
[JsonConverter(typeof(ListConverter<IGenre, Genre>))]
public IList<IGenre> Genres { get; set; }
~~~~
}
JsonConverter example:
public class ListConverter<I, T> : JsonConverter
{
public override bool CanWrite => false;
public override bool CanRead => true;
public override bool CanConvert(Type objectType)
{
return objectType == typeof(I);
}
public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
{
throw new InvalidOperationException("Use default serialization.");
}
public override object ReadJson(JsonReader reader,
Type objectType, object existingValue,
JsonSerializer serializer)
{
JArray jsonArray = JArray.Load(reader);
var deserialized = (List<T>)Activator.CreateInstance(typeof(List<T>));
serializer.Populate(jsonArray.CreateReader(), deserialized);
return deserialized as IList<I>;
}
}

Categories

Resources