简体   繁体   English

如何使用DataContractJsonSerializer解析包含混合基本类型的json对象数组?

[英]How to parse a json object array containing mixed primitive types using DataContractJsonSerializer?

How can I parse the JSON object below using DataContractJsonSerializer in C#? 如何在C#中使用DataContractJsonSerializer解析下面的JSON对象?

I will need to define a class to hold the below JSON data, which includes an array of arrays of primitives of mixed types (string and integer): 我将需要定义一个类来保存以下JSON数据,其中包括混合类型(字符串和整数)的原语数组的数组:

Body:
    {
      "status": "failure",
      "staticdata": [
        [
          "2013-06-01",
          123
        ],
        [
          "2013-06-02",
          234
        ],
        [
          "2013-06-03",
          345
        ],    
        ...
      ]
    }

I tried the below answer and tried to read through DataContractJsonSerializer , 我尝试了以下答案,并试图通读DataContractJsonSerializer

DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(RootObject));

object objResponse = jsonSerializer.ReadObject(response);

RootObject jsonResponse = objResponse as RootOject;

foreach (object[] sd in jsonResponse.staticdata)
{
    foreach (object o in sd)
    {
        //Value val = v as Value;
        Value val = (Value)Convert.ChangeType(o, typeof(Value));
            log.Info("date: " + val.date);
            log.Info("crashCount: " + val.longValue);
   }
} 

but in converttype from object to Value is crashing, am I missing something here. 但是在从对象到值的转换类型崩溃时,我在这里缺少什么吗?

Value is below class: 值低于等级:

[DataContract]
public class Value
{
    [DataMember(Name = "date")]
    public string date { get; set; }

    [DataMember(Name = "longValue")]
    public long longValue{ get; set; }
}

modified code read Values (IgnoreDataMember Values), and then could able to read as below: is this the right approach? 修改后的代码读取值(IgnoreDataMember值),然后可以按以下方式读取:这是正确的方法吗?

object objResponse = jsonSerializer.ReadObject(response);

RootObject jsonResponse = objResponse as RootOject;

foreach (Value in jsonResponse.Values)
{
            log.Info("date: " + val.date);
            log.Info("longValue: " + val.longValue);
} 

If you just want to deserialize your JSON, you can use a code-generation tool like http://json2csharp.com/ or Paste JSON As Classes and get the following data model, which works perfectly well with DataContractJsonSerializer : 如果您只想反序列化JSON,则可以使用代码生成工具(例如http://json2csharp.com/)或将JSON作为类粘贴,并获得以下数据模型,该数据模型与DataContractJsonSerializer完美DataContractJsonSerializer

public class RootObject
{
    public string status { get; set; }
    public List<List<object>> staticdata { get; set; }
}

object works because DataContractJsonSerializer automatically recognizes and serializes known primitive types such as string and int . object之所以起作用,是因为DataContractJsonSerializer自动识别并序列化已知的原始类型,例如stringint

But what you may want is to deserialize your "staticdata" array to a list of classes such as this: 但是,您可能想要将"staticdata"数组反序列化为此类列表:

public class Value
{
    public string Date { get; set; }
    public int IntValue { get; set; }
}

If so, you can make use of a surrogate property in the RootObject type to do the conversion: 如果是这样,您可以使用RootObject类型中的替代属性来进行转换:

[DataContract]
public class RootObject
{
    [DataMember]
    public string status { get; set; }

    [DataMember]
    object[][] staticdata
    {
        get
        {
            if (Values == null)
                return null;
            return Values.Select(v => new object[] { v.Date, v.IntValue }).ToArray();
        }
        set
        {
            if (value == null)
                return;
            Values = value.Select(a => new Value 
                { 
                    Date = a.Length < 1 ? null : (string)Convert.ChangeType(a[0], typeof(string), CultureInfo.InvariantCulture),
                    IntValue = a.Length < 2 ? 0 : (int)Convert.ChangeType(a[1], typeof(int), CultureInfo.InvariantCulture) 
                }
                ).ToList();
        }
    }

    [IgnoreDataMember]
    public List<Value> Values { get; set; }
}

Update 更新资料

In your updated question you asked, but in converttype from object to Value is crashing, am I missing something here? 在您询问的更新问题中, 但是在从对象到值的转换类型崩溃时,我在这里缺少什么吗?

Your problem is that you are trying to use Convert.ChangeType() to convert an object to a Value , but this method is only for primitive data types that can be converted from and to strings. 您的问题是您试图使用Convert.ChangeType()object转换为Value ,但是此方法仅适用于可以在字符串之间进行转换的原始数据类型。 From the docs : 文档

ChangeType is a general-purpose conversion method that converts the object specified by value to conversionType. ChangeType是一种通用的转换方法,它将由值指定的对象转换为conversionType。 The value parameter can be an object of any type, and conversionType can also be a Type object that represents any base or custom type. value参数可以是任何类型的对象,conversionType也可以是表示任何基本或自定义类型的Type对象。 For the conversion to succeed, value must implement the IConvertible interface, because the method simply wraps a call to an appropriate IConvertible method. 为使转换成功,值必须实现IConvertible接口,因为该方法只是将对一个合适的IConvertible方法的调用包装起来。

As your Value type does not implement this interface, conversion fails. 由于您的Value类型未实现此接口,因此转换失败。

Instead, you should use Convert.ChangeType on the individual entries in the nested arrays. 相反,您应该在嵌套数组中的各个条目上使用Convert.ChangeType Given your RootObject looks like: 给定您的RootObject看起来像:

public class RootObject
{
    public string status { get; set; }
    public object [][] staticdata { get; set; }
}

You should do: 你应该做:

using System.Linq;

DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(RootObject));
var jsonResponse = (RootObject)jsonSerializer.ReadObject(response);

var query = jsonResponse.staticdata
    // For each object [] array in the outer array
    .Select(a => new Value
        {
             // Convert the inner array to a Value, using the first element for the date and the second element for the longValueand the second element for the longValue
            date = a.Length < 1 ? null : (string)Convert.ChangeType(a[0], typeof(string), CultureInfo.InvariantCulture),
            longValue = a.Length < 2 ? 0 : (long)Convert.ChangeType(a[1], typeof(long), CultureInfo.InvariantCulture)
        });

foreach (var val in query)
{
    log.Info("date: " + val.date);
    log.Info("crashCount: " + val.longValue);
}

暂无
暂无

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

相关问题 如何使用DataContractJsonSerializer解析具有可变键名的json对象 - How to parse json object with variable key names using DataContractJsonSerializer 使用DataContractJsonSerializer使用不同类型的数组反序列化json - Deserialize json with array of different types using DataContractJsonSerializer 如何使用DataContractJsonSerializer来解析嵌套的json对象? - How to use DataContractJsonSerializer to parse a nested json object? 使用DataContractJsonSerializer作为JSON数组序列化对象 - Serialize an object using DataContractJsonSerializer as a json array 使用C#DataContractJsonSerializer解析JSON命名数组 - Parse JSON named array using C# DataContractJsonSerializer 如何使用 DataContractJsonSerializer 序列化包含日期和时间属性的 JSON 字符串? - How to serialize JSON string containing date and time property using DataContractJsonSerializer? 解析包含混合类型数组的奇怪JSON的最高效方式? - Most performant way to parse strange JSON containing arrays of mixed types? 使用DataContractJsonSerializer从JSON数据填充对象数组时出错 - Error filling an object array from JSON data using DataContractJsonSerializer 如何将包含不同数据类型的JSON数组反序列化为单个对象 - How to deserialize a JSON array containing different data types to a single object 如何使用JSON.NET或DataContractJsonSerializer反序列化未类型化的对象 - How to deserialize an untyped object using JSON.NET or DataContractJsonSerializer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM