反序列化由 SignalR 作为抽象类传递的对象

shl*_*chz 7 c# json.net signalr asp.net-web-api

我有一个 WebAPI 服务器,它有一个集线器,通过发布一个Dictionary<long, List<SpecialParam>>对象来回复订阅请求。

的列表SpecialParam包含类型SpecialParamA& 的项目,SpecialParamB它们都继承了SpecialParam

当我尝试在客户端上捕获发布时:

hubProxy.On<Dictionary<long, List<SpecialParam>>>(hubMethod, res =>
{
    DoStuff();
});
Run Code Online (Sandbox Code Playgroud)

DoStuff()不调用该方法。如果我将发布返回值string更改为,并将代理更改为接收string值,DoStuff()则会调用该方法。因此,问题在于SpecialParamItem的反序列化。

我尝试在服务器端配置:

var serializer = JsonSerializer.Create();
serializer.TypeNameHandling = TypeNameHandling.All;
var hubConfig = new HubConfiguration();
hubConfig.Resolver.Register(typeof(JsonSerializer), () => serializer);
GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => serializer);
Run Code Online (Sandbox Code Playgroud)

但它没有帮助。

我也尝试添加到客户端:

HubConnection hubConnection = new HubConnection(hubPath);
hubConnection.JsonSerializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto;
hubProxy = hubConnection.CreateHubProxy(hubName);
hubProxy.JsonSerializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto;
Run Code Online (Sandbox Code Playgroud)

它也没有帮助。

在其他解决方案中,我发现人们定义了一个 new IParameterResolver,但它仅在服务器接收到集线器方法的输入时被调用,而不是在从集线器发布输出时调用。

请帮忙!

更新

这是我用 fiddle 捕捉到的:

{"$type":"Microsoft.AspNet.SignalR.Hubs.HubResponse, Microsoft.AspNet.SignalR.Core","I":"0"}
Run Code Online (Sandbox Code Playgroud)

这是服务器对客户端的回复。

更新 2

我仍在试图弄清楚如何接收它已经反序列化为Dictionary<long, List<SpecialParam>>.

shl*_*chz 3

我通过在服务中设置解决了这个问题:

public static void ConfigureApp(IAppBuilder appBuilder)
{
    ...
    var service = (JsonSerializer)GlobalHost.DependencyResolver.GetService(typeof(Newtonsoft.Json.JsonSerializer));
    service.TypeNameHandling = TypeNameHandling.All;
    ...
}
Run Code Online (Sandbox Code Playgroud)

并删除客户端中的预期类型:

hubProxy.On(hubMethod, res =>
{
    DoStuff();
});
Run Code Online (Sandbox Code Playgroud)

我收到 json 形式的响应,并使用以下命令对其进行反序列化:

var serializer = new JsonSerializer();
serializer.TypeNameHandling = TypeNameHandling.All;
JObject jObject = resp as JObject;
var specialParams = jObject.ToObject<Dictionary<long, List<SpecialParam>>>(serializer);
Run Code Online (Sandbox Code Playgroud)

我仍然不知道如何让我的客户收到已经反序列化的数据。