我在.NET 4.5.2中使用SignalR 2.2.2(最新版本)
我发现了这个错误:
无法创建类型的实例 DF.ApplicationBlocks.IPropertyValueData。类型是接口或 抽象类,无法实例化。路径'属性[0] .Id', 第1行,第881位。
问题是:
我发送了一个自定义对象的SignalR客户端(用.NET编写,使用Signal.Client包),在该对象上有一个对象数组作为接口(IPropertyValueData)。数组中的值是此接口的实现。
在signalR客户端中,我已配置为使用TypeNameHandling.Auto:
this._connection.JsonSerializer.TypeNameHandling = TypeNameHandling.Auto;
this._connection.JsonSerializer.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
this._connection.JsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
并且它正确完成,因为这是客户发送的内容的摘录:
"Properties":[
{
"$id":"20",
"$type":"DF.MailFlow.Services.Contract.Data.MailDataProperty, DF.MailFlow.Services.Contract",
"Id":"5588ce9e-30fb-45b1-afbe-1e6ad0c3e8d4",
因此定义了$ type属性并且值是正确的。 但无论如何,服务器仍会在收到消息时触发错误。
我还将服务器配置为使用TypeNameHandling.Auto,以下是集线器的配置方式(我使用Castle Windsor作为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)));
我已经检查过,当收到第一条消息时,将调用factory方法并且设置仍然具有正确的TypeNameHandling.Auto。
我也测试过以这种方式注册序列化器:
GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => JsonSerializer.Create(serializerSettings));
但是没办法,服务器总是在收到消息时触发相同的错误。
增加复杂性,应用程序运行signalr和webapi组件(在不同的URL中)。我检查过webapi没有注册任何JsonSerializer,所使用的Windsor容器对于两个组件都是相同的。
有什么想法吗?
编辑#1:
我刚试过这张票https://github.com/SignalR/SignalR/issues/3304
似乎令人难以置信的是,即使有人制作PR(https://github.com/SignalR/SignalR/pull/3343),也会在3年内没有任何修复的情况下列出错误
所以现在我试图找到一个解决方法......
答案 0 :(得分:0)
这个问题显然是由于SignalR中的错误
造成的此link中发布的解决方法有效,即注册自定义解析程序:
private class Resolver : DefaultParameterResolver
{
private readonly JsonSerializer _serializer;
public Resolver(JsonSerializer serializer)
{
_serializer = serializer;
}
private FieldInfo _valueField;
public override object ResolveParameter(ParameterDescriptor descriptor, Microsoft.AspNet.SignalR.Json.IJsonValue value)
{
if (value.GetType() == descriptor.ParameterType)
{
return value;
}
if (_valueField == null)
_valueField = value.GetType().GetField("_value", BindingFlags.Instance | BindingFlags.NonPublic);
var json = (string)_valueField.GetValue(value);
using (var reader = new StringReader(json))
return _serializer.Deserialize(reader, descriptor.ParameterType);
}
}
关于如何解决此错误的讨论现在在this ticket,所以你可以在那里找到(希望)解决它