C# 无法将JSON数组反序列化为类型
我正在使用Newtonsoft JSON.NET包来反序列化我的响应。这是一个从Omniture中提取可用指标的调用的示例响应C# 无法将JSON数组反序列化为类型,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我正在使用Newtonsoft JSON.NET包来反序列化我的响应。这是一个从Omniture中提取可用指标的调用的示例响应 [ {"rsid":"somersid", "site_title":"somesitetitle", "available_metrics":[ {"metric_name":"averagepagedepth","display_name":"Average Page Depth"}, {"metric_name":"averagetimespe
[
{"rsid":"somersid",
"site_title":"somesitetitle",
"available_metrics":[
{"metric_name":"averagepagedepth","display_name":"Average Page Depth"},
{"metric_name":"averagetimespentonpage","display_name":"Average Time Spent on Page"},
{"metric_name":"averagetimespentonsite","display_name":"Average Time Spent on Site"},
{"metric_name":"averagevisitdepth","display_name":"Average Visit Depth"},
{"metric_name":"customersdaily","display_name":"Daily Unique Customers"},
{"metric_name":"customersloyal","display_name":"Loyal Customers"},
{"metric_name":"customersmonthly","display_name":"Monthly Unique Customers"},
{"metric_name":"customersnew","display_name":"New Customers"},
{"metric_name":"customersquarterly","display_name":"Quarterly Unique Customers"}
]
}
]
对于我想要反序列化到的类,我首先尝试了svcutil根据其模式生成的类。它正确地创建了类,并且当反序列化一个简单对象时,它们似乎可以工作。但任何带有嵌套数组(如上所述)的操作都失败,出现“无法将JSON数组反序列化为类型”错误。仔细检查后,svcutil生成的类使用如下数组:
public partial class report_suite_metrics {
public string rsid { get; set;} ;
public string site_title { get; set;} ;
public metric[] available_metrics { get; set;} ;
}
public partial class metric {
public string metric_name {get; set;}
public string display_name {get; set;}
}
也许JSON.NET正试图将该数组强制设置为我认为的通用列表。我看到的所有JSON.NET示例都使用List来处理子数组,因此我创建了新的类来使用json2csharp实用工具进行测试(http://json2csharp.com/)得到这个:
public class AvailableMetric {
public string metric_name { get; set; }
public string display_name { get; set; }
}
public class RootObject {
public string rsid { get; set; }
public string site_title { get; set; }
public List<AvailableMetric> available_metrics { get; set; }
}
公共类可用性度量{
公共字符串度量_name{get;set;}
公共字符串显示\u名称{get;set;}
}
公共类根对象{
公共字符串rsid{get;set;}
公共字符串site_title{get;set;}
公共列表可用_度量{get;set;}
}
这看起来与所有JSON.NET示例完全一致。但它抛出了完全相同的错误:(什么原因?有人遇到过这种问题吗?这似乎是一个非常简单和常见的情况,所以我很惊讶它并没有像预期的那样正常工作。感谢您提供的两组类型都有效;问题是返回的源数据是核心类型的数组,而不是单个实例。请注意您提供的JSON示例中的方括号对整个数据单元进行四舍五入 下面是一个测试控制台应用程序,您可以使用它检查您看到的JSON 要使用它,请将上面提供的JSON复制到任意文本文件中,然后从应用程序中打开它 请注意,反序列化为数组工作正常,但单个元素(根据您的期望)失败 如果创建的示例文本文件包含相同的示例数据,但没有外部的[]方括号,则会看到数组反序列化失败,单个元素工作正常
using System.Windows.Forms;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace RptSuiteMetricsTest1
{
class Program
{
public class report_suite_metrics
{
public string rsid { get; set; }
public string site_title { get; set; }
public metric[] available_metrics { get; set; }
}
public class metric
{
public string metric_name { get; set; }
public string display_name { get; set; }
}
public class AvailableMetric
{
public string metric_name { get; set; }
public string display_name { get; set; }
}
public class RootObject
{
public string rsid { get; set; }
public string site_title { get; set; }
public List<AvailableMetric> available_metrics { get; set; }
}
[STAThread]
static void Main(string[] args)
{
OpenFileDialog dlg = new OpenFileDialog();
DialogResult dr = dlg.ShowDialog();
if (dr != DialogResult.OK) { return; }
// NOTE: ...or replace this with a string containing the json data to test.
string jsonData = System.IO.File.ReadAllText(dlg.FileName);
Console.WriteLine("Deserialize as array");
try
{
report_suite_metrics[] dataset = JsonConvert.DeserializeObject<report_suite_metrics[]>(jsonData);
Console.WriteLine("{0} items found.", dataset.Length);
}
catch (Exception ex)
{
Console.WriteLine("Exception of type {0}", ex.GetType().Name);
}
Console.WriteLine("Deserialize as array, alternate type");
try
{
RootObject[] dataset = JsonConvert.DeserializeObject<RootObject[]>(jsonData);
Console.WriteLine("{0} items found.", dataset.Length);
}
catch (Exception ex)
{
Console.WriteLine("Exception of type {0}", ex.GetType().Name);
}
Console.WriteLine();
Console.WriteLine("Deserialize as single item");
try
{
report_suite_metrics dataset = JsonConvert.DeserializeObject<report_suite_metrics>(jsonData);
Console.WriteLine("rsid=\"{0}\"", dataset.rsid);
}
catch (Exception ex)
{
Console.WriteLine("Exception of type {0}", ex.GetType().Name);
}
Console.WriteLine("Deserialize as single item, alternate type");
try
{
RootObject dataset = JsonConvert.DeserializeObject<RootObject>(jsonData);
Console.WriteLine("rsid=\"{0}\"", dataset.rsid);
}
catch (Exception ex)
{
Console.WriteLine("Exception of type {0}", ex.GetType().Name);
}
Console.ReadKey();
}
}
}
使用System.Windows.Forms;
使用Newtonsoft.Json;
使用Newtonsoft.Json.Serialization;
命名空间RtpSuiteMetricStest1
{
班级计划
{
公共类报告\u套件\u度量
{
公共字符串rsid{get;set;}
公共字符串site_title{get;set;}
公共度量[]可用_度量{get;set;}
}
公共类度量
{
公共字符串度量_name{get;set;}
公共字符串显示\u名称{get;set;}
}
公共类可用性度量
{
公共字符串度量_name{get;set;}
公共字符串显示\u名称{get;set;}
}
公共类根对象
{
公共字符串rsid{get;set;}
公共字符串site_title{get;set;}
公共列表可用_度量{get;set;}
}
[状态线程]
静态void Main(字符串[]参数)
{
OpenFileDialog dlg=新建OpenFileDialog();
DialogResult dr=dlg.ShowDialog();
如果(dr!=DialogResult.OK){return;}
//注意:…或者将其替换为包含要测试的json数据的字符串。
字符串jsonData=System.IO.File.ReadAllText(dlg.FileName);
WriteLine(“反序列化为数组”);
尝试
{
report_suite_metrics[]dataset=JsonConvert.DeserializeObject(jsonData);
WriteLine(“{0}项已找到。”,dataset.Length);
}
捕获(例外情况除外)
{
WriteLine(“类型{0}的异常”,例如GetType().Name);
}
WriteLine(“反序列化为数组,替换类型”);
尝试
{
RootObject[]dataset=JsonConvert.DeserializeObject(jsonData);
WriteLine(“{0}项已找到。”,dataset.Length);
}
捕获(例外情况除外)
{
WriteLine(“类型{0}的异常”,例如GetType().Name);
}
Console.WriteLine();
WriteLine(“反序列化为单个项”);
尝试
{
report_suite_metrics dataset=JsonConvert.DeserializeObject(jsonData);
WriteLine(“rsid=\“{0}\”,dataset.rsid);
}
捕获(例外情况除外)
{
WriteLine(“类型{0}的异常”,例如GetType().Name);
}
WriteLine(“反序列化为单个项,替换类型”);
尝试
{
RootObject dataset=JsonConvert.DeserializeObject(jsonData);
WriteLine(“rsid=\“{0}\”,dataset.rsid);
}
捕获(例外情况除外)
{
WriteLine(“类型{0}的异常”,例如GetType().Name);
}
Console.ReadKey();
}
}
}
返回的单个项目周围有方括号;是否反序列化为类型报告套件\u度量[]
或report\u suite\u metrics
?前者应该有效,后者会给出您看到的错误。@meklarian我不敢相信我错过了,这正是导致问题的原因,感谢您给我第二双眼睛!请继续并将您的评论作为答案发布,以便我能为您赢得信任,再次感谢!