繁体   English   中英

创建 ac# 类以接受 JSON 数组

[英]Creating a c# class to accept a JSON array

我正在尝试将来自 WEB API 的 JSON 流响应反序列化为 C# 对象。 电话是

(code before)
return DeserializeJsonFromStream<DistanceMatrixObject>(stream)

流式 JSON 响应是

[ {
  "id" : "904506056107888640",
  "type" : "SENT",
  "from" : "",
  "to" : "27836500923",
  "body" : "Testing of API in FreeQ code",
  "encoding" : "TEXT",
  "protocolId" : 0,
  "messageClass" : 0,
  "submission" : {
    "id" : "1-00000000001100359398",
    "date" : "2020-10-31T23:04:08Z"
  },
  "status" : {
    "id" : "ACCEPTED.null",
    "type" : "ACCEPTED",
    "subtype" : null
  },
  "relatedSentMessageId" : null,
  "userSuppliedId" : "testing123",
  "numberOfParts" : null,
  "creditCost" : null
} ]

c#对象类是

public class SMSResponseObject
{
    [JsonPropertyName("SMSResponseBody")]
    public List<SMSResponseBody> SMSResponseBodies { get; set; }
}

public class SMSResponseBody
{
    [JsonPropertyName("id")]
    public string Id { get; set; }

    [JsonPropertyName("type")]
    public string Type { get; set; }

    [JsonPropertyName("from")]
    public string From { get; set; }

    [JsonPropertyName("to")]
    public string To { get; set; }

    [JsonPropertyName("body")]
    public string Body { get; set; }

    [JsonPropertyName("encoding")]
    public string Encoding { get; set; }

    [JsonPropertyName("protocolId")]
    public int ProtocolId { get; set; }

    [JsonPropertyName("messageClass")]
    public int MessageClass { get; set; }

    [JsonPropertyName("submission")]
    public Submission Submission { get; set; }

    [JsonPropertyName("status")]
    public Status Status { get; set; }

    [JsonPropertyName("relatedSentMessageId")]
    public object RelatedSentMessageId { get; set; }

    [JsonPropertyName("userSuppliedId")]
    public object UserSuppliedId { get; set; }

    [JsonPropertyName("numberOfParts")]
    public object NumberOfParts { get; set; }

    [JsonPropertyName("creditCost")]
    public object CreditCost { get; set; }
}
public class Status
{
    [JsonPropertyName("id")]
    public string Id { get; set; }

    [JsonPropertyName("type")]
    public string Type { get; set; }

    [JsonPropertyName("subtype")]
    public object Subtype { get; set; }
}

我得到的错误响应是

Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'SMSResponseObject' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '', line 1, position 1.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureArrayContract(JsonReader reader, Type objectType, JsonContract contract)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)

我有一种感觉,我在这里遗漏了一些重要的东西,我将不胜感激,因为我不是面向对象的 c# 编程专家。

该错误在问题所在方面非常明确:

无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“SMSResponseObject”,因为该类型需要 JSON 对象(例如 {"name":"value"})才能正确反序列化

JSON 是一个集合(即被[]包围)。 并且您试图反序列化为单个对象(例如SMSResponseObject ),这会导致错误。

您应该直接反序列化为List<SMSResponseBody>

return DeserializeJsonFromStream<List<SMSResponseBody>>(stream)

或者,发件人需要将 JSON 数组包装在与您的SMSResponseObject类匹配的根属性中:

{
  "SMSResponseBody": [ {
    "id" : "904506056107888640",
    "type" : "SENT",
    "from" : "",
    "to" : "27836500923",
    "body" : "Testing of API in FreeQ code",
    "encoding" : "TEXT",
    "protocolId" : 0,
    "messageClass" : 0,
    "submission" : {
      "id" : "1-00000000001100359398",
      "date" : "2020-10-31T23:04:08Z"
    },
    "status" : {
      "id" : "ACCEPTED.null",
      "type" : "ACCEPTED",
      "subtype" : null
    },
    "relatedSentMessageId" : null,
    "userSuppliedId" : "testing123",
    "numberOfParts" : null,
    "creditCost" : null
  } ]
}

您需要反序列化为实现错误消息中建议的 ICollection 或 IList 的对象。

这是一个使用您提供的相同代码的工作示例。

解串器(控制台应用程序)

using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;

namespace json_to_obj
{
    class Program
    {
        static void Main(string[] args)
        {
            var serializer = Newtonsoft.Json.JsonSerializer.CreateDefault();
            var data = GetRawData();
            data.Position = 0;
            var obj = serializer.Deserialize<List<SMSResponseBody>>(new JsonTextReader(new StreamReader(data)));
        }

        static Stream GetRawData() {
           var data = new MemoryStream();
           using(var stream = File.OpenRead("data.txt")) {
              stream.CopyTo(data);
           } 
           return data;
        }
    }    
}

模型 (POCO)

using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace json_to_obj
{
   public class SMSResponseObject
   {
      [JsonPropertyName("SMSResponseBody")]
      public List<SMSResponseBody> SMSResponseBodies { get; set; }
   }

   public class SMSResponseBody
   {
      [JsonPropertyName("id")]
      public string Id { get; set; }

      [JsonPropertyName("type")]
      public string Type { get; set; }

      [JsonPropertyName("from")]
      public string From { get; set; }

      [JsonPropertyName("to")]
      public string To { get; set; }

      [JsonPropertyName("body")]
      public string Body { get; set; }

      [JsonPropertyName("encoding")]
      public string Encoding { get; set; }

      [JsonPropertyName("protocolId")]
      public int ProtocolId { get; set; }

      [JsonPropertyName("messageClass")]
      public int MessageClass { get; set; }

      [JsonPropertyName("submission")]
      public Submission Submission { get; set; }

      [JsonPropertyName("status")]
      public Status Status { get; set; }

      [JsonPropertyName("relatedSentMessageId")]
      public object RelatedSentMessageId { get; set; }

      [JsonPropertyName("userSuppliedId")]
      public object UserSuppliedId { get; set; }

      [JsonPropertyName("numberOfParts")]
      public object NumberOfParts { get; set; }

      [JsonPropertyName("creditCost")]
      public object CreditCost { get; set; }
   }
   
   public class Status
   {
      [JsonPropertyName("id")]
      public string Id { get; set; }

      [JsonPropertyName("type")]
      public string Type { get; set; }

      [JsonPropertyName("subtype")]
      public object Subtype { get; set; }
   }

   public class Submission
   {
      [JsonPropertyName("id")]
      public string Id { get; set; }

      [JsonPropertyName("date")]
      public DateTime Date { get; set; }
   }
}

数据(文件“data.txt”中的原始 JSON 文本)

[ {
  "id" : "904506056107888640",
  "type" : "SENT",
  "from" : "",
  "to" : "27836500923",
  "body" : "Testing of API in FreeQ code",
  "encoding" : "TEXT",
  "protocolId" : 0,
  "messageClass" : 0,
  "submission" : {
    "id" : "1-00000000001100359398",
    "date" : "2020-10-31T23:04:08Z"
  },
  "status" : {
    "id" : "ACCEPTED.null",
    "type" : "ACCEPTED",
    "subtype" : null
  },
  "relatedSentMessageId" : null,
  "userSuppliedId" : "testing123",
  "numberOfParts" : null,
  "creditCost" : null
} ]

反序列化列表

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM