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_name
和 last_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; }
}
每个解决方案都与一种序列化引擎(不)兼容。
我正在做一个项目并尝试将 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_name
和 last_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; }
}
每个解决方案都与一种序列化引擎(不)兼容。