Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions JsonSubTypes.Tests/GenericTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using Newtonsoft.Json;
using NUnit.Framework;

namespace JsonSubTypes.Tests
{[JsonConverter(typeof(JsonSubtypes), "Type")]
[JsonSubtypes.KnownSubType(typeof(Some<>), "Some")]
public interface IResult
{
string Type { get;}
}

public class SomeInteger: Some<int> {
public override string ResultType { get { return "SomeInteger"; }}

}

public class SomeText: Some<string> {
public override string ResultType { get { return "SomeText"; }}

}

[JsonConverter(typeof(JsonSubtypes), "ResultType")]
//[JsonSubtypes.KnownSubType(typeof(SomeInteger), "SomeInteger")]
//[JsonSubtypes.KnownSubType(typeof(SomeText), "SomeText")]
public abstract class Some<T> : IResult
{

public string Type { get { return "Some"; }}
public abstract string ResultType { get; }
public T Value { get; set; }
}

[TestFixture]
public class GenericTests
{


[Test]
public void DeserializingSubTypeWithDateParsesCorrectly()
{
var input = new SomeInteger {Value = 42};
var json = JsonConvert.SerializeObject(input);

Console.WriteLine(json);

var result = JsonConvert.DeserializeObject<IResult>(json);

Console.WriteLine(result);
}
}
}
19 changes: 17 additions & 2 deletions JsonSubTypes/JsonSubtypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -392,14 +392,29 @@ private static Type GetTypeByName(string typeName, TypeInfo parentType)
typeByName = insideAssembly.GetType(searchLocation + typeName, false, true);
}

var typeByNameInfo = ToTypeInfo(typeByName);
if (typeByNameInfo != null && parentType.IsAssignableFrom(typeByNameInfo))
TypeInfo typeByNameInfo = ToTypeInfo(typeByName);
if (typeByNameInfo == null)
{
return null;
}

if (parentType.IsAssignableFrom(typeByNameInfo) || (parentType.IsGenericType && IsSubclassOfRawGeneric(parentType, typeByNameInfo)))
{
return typeByName;
}

return null;
}

static bool IsSubclassOfRawGeneric(TypeInfo generic, TypeInfo toCheck) {
TypeInfo cur = toCheck;
TypeInfo objectTypeInfo = ToTypeInfo(typeof(object));
while (generic != cur && toCheck != objectTypeInfo) {
cur = toCheck.IsGenericType ? ToTypeInfo(toCheck.GetGenericTypeDefinition()) : toCheck;
toCheck = ToTypeInfo(toCheck.BaseType);
}
return generic == cur;
}

private static Type GetTypeFromMapping(NullableDictionary<object, Type> typeMapping, JToken discriminatorToken, JsonSerializer serializer)
{
Expand Down