0

所以 JSON 将会出现一段时间,我将不得不学习它是如何工作的......

在 Azure pubsub 中,我发送如下消息:

 var json = System.Text.Json.JsonSerializer.Serialize(<<a class in C#>> );
 await webPubSubServiceClient.SendToAllAsync(content: json, contentType: 
  ContentType.ApplicationJson);

当我在另一边得到它时(从 ResponseMessage.TEXT 中读取),我得到了这个:

{
  "type": "message",
  "from": "server",
  "dataType": "json", //binary/json/text
  "data": {
    "event": "connected",
    "userId": "WPFClient_162035",
    "connectionId": "",
    "message": "User: >WPFClient_162035< has joined hub:>chat<",
    "type": "system",
    "group": "",
    "typeName": "WebhostGeneratedMessage"
  }
}

webPubSubServiceClient 已经包装了我在这个结构中创建的 JSON:

 {
      "type": "message",
      "from": "server",
      "dataType": "json", //binary/json/text
      "data": {}

问题在于我正在发送各种 JSON 有效负载,并且包装器没有信封字段告诉我如何反序列化“数据”中的内容 - 因为在该类中我有一个带有属性的基类填写我正在使用的 typeName。

所以当我这样做时:

TypeOfMessageReceived? deserialized = System.Text.Json.JsonSerializer.Deserialize<TypeOfMessageReceived>(body);

反序列化对数据元素有爆炸的变化,因为数据元素可以是我序列化的任何类。

那么如何使用 C# 中的类读取数据?我是否将其读取为 JSONElement/JSONDocument 并解析我的方式?如果是这样,我希望有一些最佳实践的例子。

我认为我的另一个选择是简单地将要发送的消息定义为“TEXT”,然后反序列化为基类,获取我需要的段,反序列化该片段?

我在这里遗漏了一些东西,因为 JSON 协议应该在这里帮助我,而不是妨碍我……或者我只是认为类型太强了?

我正在使用 NET6,所以我希望我们有一些我不知道的新功能。正如我所说,我正在寻找使用这项新服务的最佳实践。

提前致谢。

4

1 回答 1

0

如何检查第typeName一个然后反序列化为强类型:

using (var document = JsonDocument.Parse(inputMessage))
{
    var type = document.RootElement.GetProperty("type").GetString();
    if (type == "message")
    {
        var data = document.RootElement.GetProperty("data");
        if (data.ValueKind == JsonValueKind.Object && data.TryGetProperty("typeName", out var typeNameProperty))
        {
            var typeName = typeNameProperty.GetString();
            if (typeName == "WebhostGeneratedMessage")
            {
                var message = data.Deserialize<WebhostGeneratedMessage>(new JsonSerializerOptions(JsonSerializerDefaults.Web));

                Console.WriteLine(message?.Message ?? throw new ArgumentNullException());
            }
        }
    }
}

一个完全可运行的 net6 控制台测试应用程序:


using System.Text.Json;

var inputMessage = JsonSerializer.Serialize(
    new
    {
        type = "message",
        from = "server",
        dataType = "json",
        data = new
        {
            @event = "connected",
            userId = "WPFCLient_142322",
            connectionId = "12345",
            message = "User a joined",
            type = "system",
            group = "group1",
            typeName = "WebhostGeneratedMessage"

        }
    });

using (var document = JsonDocument.Parse(inputMessage))
{
    var type = document.RootElement.GetProperty("type").GetString();
    if (type == "message")
    {
        var data = document.RootElement.GetProperty("data");
        if (data.ValueKind == JsonValueKind.Object && data.TryGetProperty("typeName", out var typeNameProperty))
        {
            var typeName = typeNameProperty.GetString();
            if (typeName == "WebhostGeneratedMessage")
            {
                var message = data.Deserialize<WebhostGeneratedMessage>(new JsonSerializerOptions(JsonSerializerDefaults.Web));

                Console.WriteLine(message?.Message ?? throw new ArgumentNullException());
            }
        }
    }
}

public class WebhostGeneratedMessage
{
    public string? Event { get; set; }
    public string? UserId { get; set; }
    public string? ConnectionId { get; set; }
    public string? Message { get; set; }
    public string? Type { get; set; }
    public string? Group { get; set; }
    public string? TypeName { get; set; } = nameof(WebhostGeneratedMessage);
}

于 2022-01-17T02:36:49.417 回答