我有一个扩展方法将json字符串序列化为对象
/// <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;
}
}
}
我定义了几个类来表示我想要将JSON字符串反序列化为的对象:
/// <summary>
/// Represents a record and it's properties
/// </summary>
[DataContract]
public class Record
{
/// <summary>
/// Dictionary of properties for the record
/// </summary>
[DataMember(Name = "properties")]
public Dictionary<string, object> Properties { get; set; }
}
[DataContract]
public class Comments
{
[DataMember(Name = "Comment")]
public CommentItem[] CommentCollection { get; set; }
public static Comments FromJSON(string sJSON)
{
return sJSON.FromJSON<Comments>();
}
}
[DataContract]
public class CommentItem
{
[DataMember(Name = "CommentId")]
public string CommentId {get; set;}
[DataMember(Name = "CommentBody")]
public string CommentBody { get; set; }
}
只是注意我使用了Dictionary属性,因为我正在使用的供应商REST API没有我可以编写的严格属性集。
我有一个从REST API返回的JSON字符串,如下所示:
{
"properties" : {
"Id" : "12644",
"Description" : "Test",
"Comments" : "{\"Comment\":[{\"CommentId\":\"cfe6235f-40ee-421d-807f-30315a9f1e08\",\"CommentBody\":\"Test 123\"},{\"CommentId\":\"8d89eef6577e22762650ee5225eb9402ca2f\","CommentBody\":\"Test XYZ\"}]}"
}
}
请注意,Comments属性包含一个转义的JSON字符串,它基本上是JSON字符串中的JSON字符串。
现在我有一个反序列化的扩展方法和一个对象模型,我可以反序列化:
Record r = sMyJSON.FromJSON<Record>();
Comments c = r.Properties["Comments"].ToString().FromJSON<Comments>();
正如您所看到的,这是一个两步过程,我需要通过明确指定Comment类类型来反序列化comment属性项。
有没有办法让deserializer在第一步中智能地将Properties集合中的项目反序列化为适当的类类型?因此,即使Record.Properties是Dictionary,对象也会是一个注释实例?
我通过在JSON序列化程序中指定已知类型来尝试这个:
...
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T), new DataContractJsonSerializerSettings()
{
UseSimpleDictionaryFormat = true,
KnownTypes = new Type[]
{
typeof(ObjectModel.Comments),
typeof(string[]),
typeof(List<string>),
typeof(int[]),
typeof(List<int>)
}
});
return (T)ser.ReadObject(strJSON);
...
答案 0 :(得分:0)
我不确定这是否能回答您的问题,但这是我如何使用json.net序列化和反序列化自定义类:
public class AssignmentHistory
{
public DateTime WeekOfAssignment { get; set; }
public int TalkType { get; set; }
public int StudentID_FK { get; set; }
public int AssistantID_FK { get; set; }
public int CounselPoint { get; set; }
public bool HasBeenEmailed { get; set; }
public bool SlipHasBeenPrinted { get; set; }
}
public static string ASSIGNMENT_TYPES_FILENAME = @"C:\AYttFMApp\AYttFMScheduler\AssignmentTypes.json";
. . .
public static List<AssignmentHistory> AssignmentHistList;
. . .
public static void SerializeAssignmentHistFile(string fileStorageLoc)
{
var jsonAssignmentHist = JsonConvert.SerializeObject(AssignmentHistList); //_assignmentHistList);
System.IO.File.WriteAllText(fileStorageLoc, jsonAssignmentHist);
}
public static List<AssignmentHistory> DeserializeAssignmentHistFile()
{
if (!System.IO.File.Exists(ASSIGNMENT_HISTORY_FILENAME))
{
var assignmentFile =
System.IO.File.Create(ASSIGNMENT_HISTORY_FILENAME);
assignmentFile.Close();
return null;
}
var assignmentHistFile =
System.IO.File.ReadAllText(ASSIGNMENT_HISTORY_FILENAME);
var assignmentHistDeserialized =
JsonConvert.DeserializeObject<List<AssignmentHistory>>(assignmentHistFile);
if (null != assignmentHistDeserialized) return
assignmentHistDeserialized;
var assignmentHistoryList = new List<AssignmentHistory>();
return assignmentHistoryList;
}