我无法弄清楚如何使用匿名对象解析JSON对象。这是我的JSON:
{
"success": true,
"affectedRows": 2,
"data": [
{
"success": true,
"affectedRows": 1,
"data": [
{
"ID": 376,
"SomeOtherID": 0,
"StringValue": "Fan"
}
]
},
{
"success": true,
"affectedRows": 1,
"data": []
},
{
"success": true,
"data": {
"ID": 401,
"DateTime": "2014-10-03 18:52:48"
}
}
]
}
我有一个类,其中包含作为我期待的JSON响应模型的类。
public class JSONObjects
{
public class Success
{
public bool success {get;set}
public int affectedRows {get;set;}
}
public class Response
{
public int ID {get;set;}
public int SomeOtherID {get;set;}
public string StringValue {get;set;}
}
public class FirstResponse : Success
{
public Response[] data {get;set;}
}
public class SecondResponse : Success
{
public object[] data {get;set;}
}
public class TimeData
{
public int ID {get;set;}
public string DateTime {get;set;}
}
public class FullTimeData
{
public bool success {get;set;}
public TimeData data {get;set;}
}
public class FullResponse : Success
{
// ??? anonymous object[] data ???
}
}
用法:
FullResponse data = JsonConvert.DeserializeObject<JSONObjects.FullResponse>(jsonString, jsonSerializerSettings);
Debug.WriteLine(data.data[0].anonymousObject0.data[0].StringValue);
如何将匿名对象作为对象数组放在FullResponse类中,然后再访问它们?
答案 0 :(得分:1)
dynamic
。可以将JSON反序列化为完全动态类型,但NewtonSoft.Json不会开箱即用;可以找到更多信息here。但是,我几乎不惜任何代价避免使用动态,因为它绕过了C#开发人员生成正确代码的最强大的工具;编译器语法检查。 Fat-finger是一个标识符,或者在方法调用中使用方括号而不是括号,只要 可以是有效的C#语法,编译器将不再关心它是否 < / em>有效,让你在运行时找到。
保持静止的土地,&#34;数据&#34;字段将是反序列化中最大的问题,因为它只是一个实例中的一个数组类型,它是一个结构类型。如果没有某种鉴别器,或者字段名称和字段类型之间的一对一关系,我就无法想到一种方法可以将此结构反序列化为强类型图形。
让我们说&#34;数据&#34;永远是一个阵列; JSON中唯一的变化是围绕最后一个对象的实际数据结构的一组方括号:
{
"success": true,
"affectedRows": 2,
"data": [
{
"success": true,
"affectedRows": 1,
"data": [
{
"ID": 376,
"SomeOtherID": 0,
"StringValue": "Fan"
}
]
},
{
"success": true,
"affectedRows": 1,
"data": []
},
{
"success": true,
"data": [
{
"ID": 401,
"DateTime": "2014-10-03 18:52:48"
}
]
}
]
}
在这种情况下,我要做的是定义一个单一的自嵌套类型,它具有您可以在此图的任何级别找到的每个数据字段的属性:
public class RawResponse
{
public bool? success {get;set}
public int? affectedRows {get;set;}
public int? ID {get;set;}
public int? SomeOtherID {get;set;}
public string StringValue {get;set;}
public string DateTime {get;set;}
public RawResponse[] data {get;set;}
}
这将允许您将JSON反序列化为静态类型的对象图。然后,您可以根据设置的字段添加一个生成Response
的特定派生实现的方法:
public class RawResponse : Response
{
public bool? success {get;set}
public int? affectedRows {get;set;}
public int? ID {get;set;}
public int? SomeOtherID {get;set;}
public string StringValue {get;set;}
public string DateTime {get;set;}
public RawResponse[] data {get;set;}
public Response ToResponse()
{
if(ID.HasValue && SomeOtherID.HasValue && StringValue.)
return new OtherIdResponse{
ID = ID,
SomeOtherID = SomeOtherID,
StringValue = StringValue
};
if(ID.HasValue && DateTime.HasValue)
return new DateTimeResponse{ID = ID, DateTime = DateTime};
//default case; success and child data with optional affectedRows
return new CompoundResponse{
success = success,
affectedRows = affectedRows, // can be null
data = data.Select(d=>d.ToResponse())
.ToArray()
};
}
}
显然,您需要与您已有的对象类似的对象,这些对象都来自一个共同的回应&#34;。
最后一个障碍是知道任何给定元素的具体类型。为此,我推荐一个&#34;鉴别器&#34 ;;提供简单,唯一类型标识符的公共属性:
public abstract class Response
{
public string ReponseTypeName{ get { return GetType().Name; } }
}