【问题标题】:Problem with DeserializeObject Json StringDeserializeObject Json 字符串的问题
【发布时间】:2020-03-22 21:40:08
【问题描述】:

我从 API 中得到以下 json 字符串格式:

{
   "Items":[
      {
         "Item":{
            "Codes":{},
            "Date":1523539700000,
            "Name":"Item1",
            "Price":"15"
         }
      },
      {
         "Item":{
            "Codes":{
               "productcode":"a",
               "departmentcode":"b",
               "storecode":"c"
            },
            "Date":1523537700000,
            "Name":"Item2",
            "Price":"20"
         }
      },
      {
         "Item":{
            "Codes":{
               "productcode":"a",
               "departmentcode":"b",
               "storecode":"c"
            },
            "date":1523539700000,
            "name":"Item3",
            "price":"30"
         }
      }
   ]
}

我对 Codes 元素不感兴趣,然后创建了以下类:

public class Item
    {
        [JsonConverter(typeof(ConvertItemDateTime))]
        [JsonProperty(PropertyName = "dateReceived")]
        public DateTime DateReceived { get; set; }
        [JsonProperty(PropertyName = "name")]
        public string Name{ get; set; }
        [JsonProperty(PropertyName = "price")]
        public double Price{ get; set; }
        public IList<Items> itemListResults { get; set; } //For view
        public int productid; // Added for view
    }

然后我尝试解析它...

JObject jsondata = JObject.Parse(responseToString(response))
var values = json.GetValue("Items");

...此时我可以看到变量“值”仍然包含每个项目中的每个值(日期、名称、价格)。然后我尝试反序列化它......

IList<Items> itemList = new List<Items>();
itemList = JsonConvert.DeserializeObject<IList<Items>>(values.ToString());

当我从这一点开始调试时,我可以看到一个列表,其中包含我期望的确切数量的项目,但所有值(日期、名称、价格)都是空的。 json 中的 Date 值将发生变化(从 API 端)。有时它会是一个很长的日期格式,有时是一个包含“[GMT]”的字符串日期格式。

我的 ConvertItemDateTime 方法如下:

public class ConvertItemDateTime : JsonConverter
    {
        private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        public override bool CanConvert(Type objectType)
        {
            Console.WriteLine(objectType);
            return true;
        }
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            Console.WriteLine(value.GetType());
            long ticks;
            if (value is DateTime)
            {
                var dateTime = (DateTime)value;
                ticks = (long)(dateTime.ToUniversalTime() - UnixEpoch).TotalMilliseconds;
            }
            else if (value is DateTimeOffset)
            {
                var dateTimeOffset = (DateTimeOffset)value;
                ticks = (long)(dateTimeOffset.ToUniversalTime() - UnixEpoch).TotalMilliseconds;
            }
            else
            {
                throw new JsonSerializationException("Expected date object value.");
            }
            if (ticks < 0)
            {
                throw new JsonSerializationException("Cannot convert date value that is before Unix epoch of 00:00:00 UTC on 1 January 1970.");
            }
            writer.WriteValue(ticks);
        }
        public override bool CanRead
        {
            get { return true; }
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            long ticks;
            if (reader.TokenType == JsonToken.Integer)
            {
                ticks = (long)reader.Value;
            }
            else if (reader.TokenType == JsonToken.String)
            {
                var stringValue = reader.Value.ToString();
                if (stringValue.Contains("[GMT]"))
                {
                    stringValue = stringValue.Substring(0, stringValue.Length - 6);
                    DateTime createdDate = DateTime.Parse(stringValue);
                    return createdDate;
                }

                if (!long.TryParse((string)reader.Value, out ticks))
                {
                    throw new JsonSerializationException("Cannot convert invalid value.");
                }
            }
            else
            {
                throw new JsonSerializationException("Unexpected token parsing date.");
            }
            if (ticks >= 0)
            {
                DateTime d = UnixEpoch.AddMilliseconds(ticks);
                Type t = objectType;
                if (t == typeof(DateTimeOffset))
                {
                    return new DateTimeOffset(d, TimeSpan.Zero);
                }
                return d;
            }
            else
            {
                throw new JsonSerializationException("Cannot convert value that is before Unix epoch of 00:00:00 UTC on 1 January 1970.");
            }
        }
    }
}

请帮助我完成这项工作。

【问题讨论】:

  • 在我看来,如果日期字段更改格式,您应该将其设置为模型中的字符串,然后在您打算使用它时进行转换。此外,您的模型与属性 DateReveived 不匹配。

标签: c# json deserialization jsonconverter


【解决方案1】:

您不能简单地反序列化为IList,您需要一个具有Items 属性的对象。例如:

public class RootObject
{
    public IList<Item> Items { get; set; }
}

我可以看到的另一个问题是您的 DateReceived 属性的 JsonProperty 需要匹配 JSON 名称,即 date

【讨论】:

    【解决方案2】:

    这是一个完整的工作示例:

    这是我的模型:

      public class RootObject
      {
        public List<ItemContainer> Items { get; set; }
      }
      public class ItemContainer
      {
        public Item Item { get; set; }
      }
      public class Item
      {
        public Codes Codes { get; set; }
        public string Date { get; set; }
        public string Name { get; set; }
        public string Price { get; set; }
      }
      public class Codes
      {
        public string Productcode { get; set; }
        public string Departmentcode { get; set; }
        public string Storecode { get; set; }
      }
    

    这就是我反序列化它的方式:

    var result = JsonConvert.DeserializeObject<RootObject>(json);//json is a string that contains the json input.
    

    我注意到您的示例存在几个问题:

    1. DataReceived 是 json 模型中不存在的属性。
    2. 您的 Json 不一致。名称、日期和价格也以小写形式出现:日期、名称和价格。你的 json 应该是一致的。
    3. 您试图在一个地方做太多事情。您应该只将日期的输入作为字符串,然后将其转换为一种或多种有用的格式或类型。让您的反序列化/序列化保持简单,免去您的麻烦。

    【讨论】:

      猜你喜欢
      • 2014-07-26
      • 1970-01-01
      • 2010-11-12
      • 1970-01-01
      • 2013-02-18
      • 2019-07-25
      • 1970-01-01
      • 2023-03-31
      相关资源
      最近更新 更多