【问题标题】:Azure PubSub / JSON subprotocol / deserialize JSON payloadAzure PubSub / JSON 子协议 / 反序列化 JSON 有效负载
【发布时间】:2022-01-11 05:26:06
【问题描述】:

所以 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,所以我希望我们有一些我不知道的新功能。正如我所说,我正在寻找使用这项新服务的最佳做法。

提前致谢。

【问题讨论】:

    标签: json json-deserialization azure-web-pubsub


    【解决方案1】:

    先检查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);
    }
    
    

    【讨论】:

    • 太棒了...非常感谢...我正在寻找解析 json 而不仅仅是序列化/反序列化过程非常感谢您的时间
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    相关资源
    最近更新 更多