通过SignalR向客户端发送不同对象列表的最佳方法是什么?
当我使用具有相同基数的对象列表时,客户端仅接收基类的属性:
class Update { }
class UpdateA { public string PropertyA {get; set;}}
class UpdateB { public string PropertyB {get; set;}}
...
IEnumerable<Update> updates = GetUpdates();
await Clients.Caller.SendAsync("update", updates);
当我使用字符串形式的预序列化数据时,serialzier将json数据转义为字符串。
IEnumerable<string> updates = GetUpdates();
await Clients.Caller.SendAsync("update", updates);
// data looks like: [ "{...}", "{...}" ]
我必须编写我自己的serialzier吗?在dotnet核心中,SignalR如何工作?
通过SignalR向客户端发送具有相同基础的不同对象的列表
您可以尝试通过创建和使用自定义转换器来满足要求,如下所示。
自定义转换器MyConverterWithTypeDiscriminator
public override void Write(Utf8JsonWriter writer, Update value, JsonSerializerOptions options)
{
writer.WriteStartObject();
if (value is UpdateA updateA)
{
writer.WriteNumber("TypeDiscriminator", (int)TypeDiscriminator.UpdateA);
writer.WriteString("PropertyA", updateA.PropertyA);
}
else if (value is UpdateB updateB)
{
writer.WriteNumber("TypeDiscriminator", (int)TypeDiscriminator.UpdateB);
writer.WriteString("PropertyB", updateB.PropertyB);
}
writer.WriteString("UpdatedAt", value.UpdatedAt);
writer.WriteEndObject();
}
基类和派生类
public class Update
{
public DateTime UpdatedAt { get; set; }
}
public class UpdateA : Update
{
public string PropertyA { get; set; }
}
public class UpdateB : Update
{
public string PropertyB { get; set; }
}
在Startup.cs中
services.AddSignalR().AddJsonProtocol(options => options.PayloadSerializerOptions.Converters.Add(new MyConverterWithTypeDiscriminator()));
In Hub方法
var updates = new List<Update>
{
new UpdateA
{
UpdatedAt=DateTime.Now.AddDays(-1),
PropertyA = "A"
},
new UpdateB
{
UpdatedAt=DateTime.Now.AddDays(-1),
PropertyB = "B"
}
};
await Clients.All.SendAsync("ReceiveUpdate", updates);
测试结果
注意:要实现您的自定义转换器,请检查此链接:https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to#support-polymorphic-deserialization