I'm using SignalR 2.2.2 (Latest release) with .NET 4.5.2
I've this error:
Could not create an instance of type DF.ApplicationBlocks.IPropertyValueData. Type is an interface or abstract class and cannot be instantiated. Path 'Properties[0].Id', line 1, position 881.
The problem is :
I've a SignalR client (written in .NET, using Signal.Client package) that send a custom object, on this object there is an array of object typed as an interface (IPropertyValueData). The values in the array is an implementation of this interface.
In the signalR client, I've configured to use TypeNameHandling.Auto :
this._connection.JsonSerializer.TypeNameHandling = TypeNameHandling.Auto;
this._connection.JsonSerializer.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
this._connection.JsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
and it does it correctly, as here is an extract of what's sent by the client:
"Properties":[
{
"$id":"20",
"$type":"DF.MailFlow.Services.Contract.Data.MailDataProperty, DF.MailFlow.Services.Contract",
"Id":"5588ce9e-30fb-45b1-afbe-1e6ad0c3e8d4",
So the $type property is defined and the value is correct. But anyway, the server still trigger the error when the message is received.
I've also configured the server to use TypeNameHandling.Auto, here is how the hub is configured (I use Castle Windsor as IoC):
var resolver = new WindsorDependencyResolver(WebAPILoader.Container);
var hubConfig = new HubConfiguration()
{
EnableJSONP = true,
EnableDetailedErrors = true,
EnableJavaScriptProxies = true,
Resolver = resolver
};
GlobalHost.DependencyResolver = resolver;
// Configure signalR and run it
app.UseCors(CorsOptions.AllowAll);
app.Map("/live", map =>
{
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR(hubConfig);
});
var serializerSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize
};
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = serializerSettings;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;
// Register in Castle.Windsor container
WebAPILoader.Container.Register(Castle.MicroKernel.Registration.Component
.For<JsonSerializer>()
.UsingFactoryMethod(() => JsonSerializer.Create(serializerSettings)));
I've checked that when the 1st message is received, the the factory method is called and the setting still have the correct TypeNameHandling.Auto.
I also tested to register the serializer this way:
GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => JsonSerializer.Create(serializerSettings));
But no way, the server always trigger the same error when the message is received.
Adding to the complexity, the application run both signalr and webapi component (in differnt url). I've checked that the webapi doesn't register any JsonSerializer, and Windsor container used is the same for both component.
Any idea ?
Edit #1:
I just ran on this ticket https://github.com/SignalR/SignalR/issues/3304
Seems just incredible that a bug is listed there without any fix for more than 3 years, even when someone made a PR (https://github.com/SignalR/SignalR/pull/3343)
So now I'm trying to find a workaround...