SignalR 不是 serializing/deserializing 自定义数据成员名称

SignalR not serializing/deserializing custom DataMember name

我正在做一个项目并尝试将 SignalR 集成到其中。我有一个带有数据合同的 class,它允许我在我的客户端上使用下划线分隔格式,并在服务器上使用标准的 Pascal Case,如下所示:

[DataContract]
public class Foo {

    [DataMember(Name = "first_name")]
    FirstName { get;set; }

    [DataMember(Name = "last_name")]
    LastName { get;set; }

    [DataMember(Name = "phone")]
    Phone { get;set; }
}

这在通过获取命令将数据传递给 Razor 页面 OnGet 和 OnPost 方法时工作正常,但在使用 SignalR 时不起作用。

当通过 SignalR 向服务器发送数据时,first_namelast_name 为空,而 phone 被正确发送。

如何让 SignalR 在 serializing/deserializing 时尊重 DataMember 名称?

我想目前您正在将数据作为对象发送,有点像这样:

Foo foo = new Foo();
_hub.Clients.All.InvokeAsync("ReceiveMessage", foo);

我建议您在服务器端手动创建 JSON 并发送,因为这样您可以更好地控制 属性 名称。

JsonProperty 属性添加到 Foo class:

[DataContract]
public class Foo {

    [DataMember(Name = "first_name")]
    [JsonProperty("first_name")]
    FirstName { get;set; }

    [DataMember(Name = "last_name")]
    [JsonProperty("last_name")]
    LastName { get;set; }

    [DataMember(Name = "phone")]
    [JsonProperty("phone")]
    Phone { get;set; }
}

并且当您发送消息时,发送 JSON 字符串而不是让 SinglaR 解析您的对象:

Foo foo = new Foo();
string json = JsonConvert.SerializeObject(foo);
_hub.Clients.All.InvokeAsync("ReceiveMessage", json);

我能够通过使用 Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson 包并在 Startup.cs

中添加以下内容来解决这个问题
services.AddSignalR()
        .AddNewtonsoftJsonProtocol();

这些字段未被序列化,因为它们的序列化属性 ([DataMember]) 与 SignalR 的默认序列化引擎 (System.Text.Json) 不兼容。

一种可能的解决方案是将序列化引擎切换到 Newtonsoft 的 JSON 实现,如@Aleksandr Albert 的回答中所建议。另一种解决方案是使用 System.Text.Json.Serialization.JsonIncludeAttribute 代替,例如

public class Foo {
    [JsonPropertyName("first_name")]
    [JsonInclude]
    FirstName { get;set; }

    [JsonPropertyName("last_name")]
    [JsonInclude]
    LastName { get;set; }

    [JsonPropertyName("phone")]
    [JsonInclude]
    Phone { get;set; }
}

每个解决方案都与一种序列化引擎(不)兼容。