C# 对象的JSON反序列化,具有部分动态属性
我正在调用一个rest服务,该服务返回JSON内容。大多数内容都有预定义的结构,但一些内容是基于传递给rest服务的参数的动态内容。 一旦我从rest服务得到响应,我想反序列化到一个对象,这样我就可以轻松地使用数据。我目前正在使用DataContractJsonSerializer来实现这一点C# 对象的JSON反序列化,具有部分动态属性,c#,json,C#,Json,我正在调用一个rest服务,该服务返回JSON内容。大多数内容都有预定义的结构,但一些内容是基于传递给rest服务的参数的动态内容。 一旦我从rest服务得到响应,我想反序列化到一个对象,这样我就可以轻松地使用数据。我目前正在使用DataContractJsonSerializer来实现这一点 /// <summary> /// Deserialize JSON formatted string to an object of a specified type /// </su
/// <summary>
/// Deserialize JSON formatted string to an object of a specified type
/// </summary>
/// <typeparam name="T">Object type to deserialize</typeparam>
/// <param name="sJSON">JSON formatted string to deserialize</param>
/// <returns>Returns an instance of an object</returns>
public static T FromJSON<T>(this string sJSON) where T : new()
{
T oValue;
using (System.IO.MemoryStream strJSON = new System.IO.MemoryStream())
{
using (System.IO.StreamWriter swJSON = new System.IO.StreamWriter(strJSON))
{
swJSON.Write(sJSON);
swJSON.Flush();
strJSON.Seek(0, System.IO.SeekOrigin.Begin);
System.Runtime.Serialization.Json.DataContractJsonSerializer ser = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
oValue = (T)ser.ReadObject(strJSON);
return oValue;
}
}
}
对象将始终具有“entities”和“metadata”属性,元数据将始终具有“status”和“count”属性,实体将始终是一个数组,数组中的每个项都将具有“type”和“properties”属性。properties对象的动态特性开始发挥作用,它将包含完全基于传递到rest服务的内容的属性
这是类定义,我一直使用它将json字符串反序列化为对象。但我不确定如何使属性部分动态化。即使我最终能得到一个名值字典,这也是可行的。理想情况下,不需要第三方json库,这是可能的吗
[DataContract]
public class Response
{
[DataMember(
public Entity[] entities { get; set; }
[DataMember(
public MetaData metadata { get; set; }
}
[DataContract]
public class Entity
{
[DataMember(
public string type { get; set; }
[DataMember()]
public Properties properties { get; set; }
}
[DataContract]
public class Properties
{
//How do I make this part dynamic?
}
[DataContract]
public class MetaData
{
[DataContract]
public enum Status
{
[EnumMember]
OK,
[EnumMember]
FAILED
}
public Status CompletionStatus { get; set; }
[DataMember()]
public string status
{
get
{
return this.CompletionStatus.ToString();
}
set
{
this.CompletionStatus = (Status)Enum.Parse(typeof(Status), value);
}
}
[DataMember()]
public int count{ get; set; }
}
所以我把你的一部分代码放到了一个控制台应用程序中,并对它进行了一些操作,你想要使用的是一个动态类型 这是我的密码:
static void Main(string[] args)
{
string test = @" [{
""type"" : ""mytest"",
""properties"" : {
""Active"" : true,
""Category"" : ""10732"",
""Description"" : ""test test test"",
""LastUpdateTime"" : 1446676525195,
""Id"" : ""12655""
}
},
{
""type"" : ""mytest1"",
""properties"" : {
""Active"" : true,
""Category"" : ""10731232"",
""Description"" : ""test test1 test"",
""LastUpdateTime"" : 144195,
""Id"" : ""126155""
}
}
]";
List<Entity> entities = JsonConvert.DeserializeObject<List<Entity>>(test);
foreach (Entity e in entities)
{
Console.WriteLine(e.properties.Active);
}
Console.ReadKey();
}
因此,由于属性是动态的,所以它从JSon中获取数据并决定其结构的外观。我使用Newtsoft进行反序列化,但概念应该保持不变。
另外要小心,因为它是动态的,某些类型(如boolean)可能无法正确转换,因此请确保在C中获得它时,要使其正确的类型匹配,请将属性更改为:
[DataMember]
public Dictionary<string, object> properties { get; set; }
将属性设置为
字典
@Rob-这似乎不起作用。“Properties”属性的计数始终为0。仔细查看一下-您还需要配置序列化程序以正确序列化JSON对象/字典-请参阅answer PostedAlternative如果您使用JSON.net进行序列化,它将自动处理这很好!比我采用的方法要好得多,即创建一个实现ISerializable的类,然后使用构造函数(SerializationInfo,StreamingContext);这是正确的答案,因为大多数对象具有固定结构,只有属性是动态的。其他答案使整个对象成为动态的。
public class Entity
{
public string type { get; set; }
public dynamic properties { get; set; }
}
[DataMember]
public Dictionary<string, object> properties { get; set; }
var ser = new DataContractJsonSerializer(typeof(T), new DataContractJsonSerializerSettings {
UseSimpleDictionaryFormat = true
});