MT3 InterfaceProxyConverter fails on deserializing json using interface

94 views
Skip to first unread message

Brian Weeres

unread,
Apr 30, 2015, 4:39:33 PM4/30/15
to masstrans...@googlegroups.com

We have a case where we put a serialized message inside another message as string data and use JsonSerializer and the Masstransit converter InterfaceProxyConvertor to deserialize the internal message. This works in MT2 but fails in MT3. Here is a simplified example:

Class Hierarchy
public interface ITestCommand
{
   
int Id { get; }
   
string Name { get; }
}
 
public class TestCommand: ITestCommand
{
   
public int Id { get; set; }
   
public string Name { get; set; }
}


Code
JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings
{
   
TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All,
   
Converters = new List<JsonConverter>(new JsonConverter[]
               
{
                   
new InterfaceProxyConverter(TypeMetadataCache.ImplementationBuilder),
               
})
});

string json = "{\"$type\":\"Command.TestCommand, TestDeserializationWithDummyClasses\",\"Id\":1,\"Name\":\"bob\"}";
using (StringReader reader = new StringReader(json))
using (JsonTextReader jsonReader = new JsonTextReader(reader))
{
   
ITestCommand cmd = serializer.Deserialize<ITestCommand>(jsonReader);
}



This will fail on the exception: 
"Type specified in JSON 'Command.TestCommand, TestDeserializationWithDummyClasses, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not compatible with 'DynamicInternal08d251996b944976b8ca3a79ccc30000.Command.ITestCommand, CommandDynamicInternal08d251996b944976b8ca3a79ccc30000, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Path '$type', line 1, position 67."

The problem seems to be in InterfaceProxyConverter. In this contrived example I can just comment out the InterfaceProxyConverter and it will deserialize just fine.
The MT2 InterfaceProxyConverter will also work fine. It will also work if I change ITestCommand to TestCommand in the Deserialize statement with both the MT2 and MT3 InterfaceProxyConverter.

It looks like the change in the InterfaceProxyConverter.ReadJson method is causing the issue. 

MT3          
 Type proxyType = _builder.GetImplementationType(objectType);            
 
return serializer.Deserialize(reader, proxyType);

If I change that to be similar to how MT2 does it then it works fine. (Not suggesting that is the fix, just pointing it out.)
           
 Type proxyType = _builder.GetImplementationType(objectType);
 
object obj = Activator.CreateInstance(proxyType);
 serializer
.Populate(reader, obj);
 
return obj;


Thanks,
Brian






















Chris Patterson

unread,
Apr 30, 2015, 6:05:25 PM4/30/15
to masstrans...@googlegroups.com
So I can fix this, by setting the serializer to ignore the types in the serialized string (TypeNameHandling.None) -- and I don't see any side effects of doing this since I never wrote type handling support into the serializer. Then it works as expected, using the proxy properly. The question is, are you really wanting the class type that is specified by the $type attribute, or is the proxy sufficient?

Brian Weeres

unread,
Apr 30, 2015, 6:28:33 PM4/30/15
to masstrans...@googlegroups.com
We likely don't want the class type. We are deserializing to an interface. In our case the outside type is a specific class but the consumer deserializing does not have the implementation. The inner type(s) is an interface type that is already marked up with the dynamicinternal markup from InterfaceProxyConverter so there is not an actual type for that interface. That is why we use the InterfaceProxyConverter class in the first place.

A real message looks something like this. We will deserialize that to IMessaging which has a property of an interface that matches ITestClass.

"{\"$type\":\"Messaging.Event.TestResult, Test.Messaging\",\"accountNumber\":5555,\"testclass\":{\"$type\":\"DynamicInternal08d251a2b9a409d44a9d24234c240000.Messaging.Interface.Model.ITestClass, Messaging.Interface.ModelDynamicInternal08d251a2b9a409d44a9d24234c240000\",\"correlationId\":\"e0e38054-b277-4ae8-adc1-baf0c0b97a5a\"}"

Hope that makes sense.

Chris Patterson

unread,
Apr 30, 2015, 6:59:15 PM4/30/15
to masstrans...@googlegroups.com
So I've committed the fix, using your code above as the verification test. Thanks. 


--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/masstransit-discuss/6e7c44b6-e644-4ed3-b37d-6fdc8b9583bc%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages