2

I'm want to serialize derived type as explained here but for signalR I want to implement my custom converter derived from JsonConverter

I added it to signalR as folows

var serializer = GlobalHost.DependencyResolver.GetService(typeof(JsonSerializer)) as JsonSerializer;
var i = new CustomTypeConverter();
serializer.Converters.Add(i);
GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => serializer);

what types should I process at public override bool CanConvert(Type objectType) when I debug this function i don't see the types that i recognize as part of my solution

Community
  • 1
  • 1
Shachaf.Gortler
  • 5,655
  • 14
  • 43
  • 71
  • How are you using the type you are trying to serialize? If it is being passed as an argument to a client hub method, the type you're looking for is likely ClientHubInvocation. The object with your type would be in the "Args" array. http://msdn.microsoft.com/en-us/library/microsoft.aspnet.signalr.hubs.clienthubinvocation(v=vs.118).aspx – halter73 Mar 05 '14 at 20:00
  • I dont see ClientHubInvocation on the trasport line, I see HubInvocation which I cannot access becase it's a private class. I also see ClientHubInfo,HubInvocation – Shachaf.Gortler Mar 06 '14 at 06:57
  • The HubInvocation class is being deserialized, not serialized. Are you trying to deserialize or serialize your type? Or both? If you're still trying to just serialize you might need to look for ConnectionMessage instead of ClientHubInvocation. ConnectionMessage.Value would contain your ClientHubInvocation. – halter73 Mar 06 '14 at 19:28
  • I'm trying to deserialize, on the server side based on $type attribute generated on the client side. – Shachaf.Gortler Mar 09 '14 at 05:20
  • 2
    Sadly, you cannot currently change how server-side inputs are deserialized by replacing/modifying the JsonSerializer. The DependencyResolver has an IParameterResolver registered which is responsible for deserializing server-side inputs. The IParameterResolver is implemented by DefaultParameterResolver which does not use the JsonSerializer registered the DependencyResolver. http://msdn.microsoft.com/en-us/library/jj919135(v=vs.118).aspx – halter73 Mar 10 '14 at 18:52

1 Answers1

8

This has been driving me nuts for hours. Thanks to halter73's comment I was able to come up with a workaround for the problem in my special situation: I need the pipeline to create interface instances for me which does not work out of the box. So the solution was the following:

class CustomResolver : Microsoft.AspNet.SignalR.Hubs.DefaultParameterResolver
{
    public override object ResolveParameter( Microsoft.AspNet.SignalR.Hubs.ParameterDescriptor descriptor, Microsoft.AspNet.SignalR.Json.IJsonValue value )
    {
        if( descriptor.ParameterType.IsInterface )
        {
            object TargetObject = <Create the object instance here>
            return value.ConvertTo( TargetObject.GetType() );
        }
        else
        {
            return value.ConvertTo( descriptor.ParameterType );
        }
    }
}

Then before you call

WebApp.Start()

Register this new parameter resolver with:

GlobalHost.DependencyResolver.Register( typeof( Microsoft.AspNet.SignalR.Hubs.IParameterResolver ), () => new CustomResolver() );
Simon Mattes
  • 4,866
  • 2
  • 33
  • 53
  • Thanks for this. I use a lot of immutable types server-side and, despite having JSON.Net happy deserializing them (and having SignalR / WebAPI use JSON.Net) I couldn't get SignalR to call my JSON.Net contract resolver. I saw from your answer that creating a parameter resolver was the appropriate way to shim my code in to SignalR to get this working. Thanks!! :) – Ian Yates Jun 01 '15 at 05:45