【发布时间】:2013-01-30 07:21:23
【问题描述】:
我们正在使用 C# System.Runtime.Serialization.Json.DataContractJsonSerializer 反序列化 JSON。它适用于普通对象,但不适用于 List。
例如,如果 json 字符串在下面,那么它可以正常工作:
{"CacheInsertDateTime":"\/Date(1360761324878)\/","Data":{"__type":"SomeObject:#ConsoleApplication1","Symbol":"some string"}}
但是如果josn在下面:
{"CacheInsertDateTime":"\/Date(1360761324878)\/","Data":[{"__type":"SomeObject:#ConsoleApplication1","Symbol":"some string"},{"__type":"SomeObject:#ConsoleApplication1","Symbol":"some other string"}]}
数据来自List<Object> 而不是List<SomeObject>。我还附上了示例解决方案,显示了同样的问题。任何帮助或指导表示赞赏。
编辑:添加代码
{
命名空间 ConsoleApplication1 { 课堂节目 { /* 一些对象类*/ [数据合约] 公共类 SomeObject { 公共 SomeObject(字符串符号) { this.Symbol = sym; } [数据成员] 公共字符串符号 { 获取;放; }
}
/* Cahe Data */
[DataContract()]
[KnownType("GetKnownTypes")]
class CacheData
{
[DataMember()]
public object Data { get; set; }
[DataMember()]
public DateTime CacheInsertDateTime { get; set; }
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
{
return GetKnownTypes();
}
public static IEnumerable<Type> GetKnownTypes()
{
if (knownTypes == null)
{
// Since reflection is costly, we will do the lookup once for the known types and persist the data in knownTypes variable
knownTypes = new List<Type>();
// first add types from DataModel assembly get types which are marked with DataContract attribute
var typesInCurrentAssembly = Assembly.GetExecutingAssembly().GetTypes().Where
(t => t.GetCustomAttributes(false).Any(attrib => attrib is DataContractAttribute));
foreach (var type in typesInCurrentAssembly)
{
// add type and list<type> also to the known types list
knownTypes.Add(type);
knownTypes.Add(typeof(List<>).MakeGenericType(type));
}
knownTypes.Add(typeof(DataTable));
}
return knownTypes;
}
private static List<Type> knownTypes = null;
}
/*Cache Response Class*/
class CacheResponse<T> where T : class
{
public CacheData CacheData { get; set; }
public T Data
{
get{return (CacheData != null && CacheData.Data.GetType() == typeof(T)) ? CacheData.Data as T: null;}
}
}
/* Main class */
static void Main(string[] args)
{
//1. first with someobject, it works same as above
string jsonString = "{\"CacheInsertDateTime\":\"\\/Date(1360761324878)\\/\",\"Data\":{\"__type\":\"SomeObject:#ConsoleApplication1\",\"Symbol\":\"some object 1\"}}";
CacheData obj = null;
byte[] byteData = Encoding.UTF8.GetBytes(jsonString);
using (MemoryStream stream = new MemoryStream(byteData))
{
var serializer = new DataContractJsonSerializer(typeof(CacheData));
obj = serializer.ReadObject(stream) as CacheData;
}
CacheResponse<SomeObject> response1 = new CacheResponse<SomeObject>();
response1.CacheData = obj;
SomeObject responseObj = response1.Data; //this response object is fine
//2. with list<someobject>, it does not work
jsonString = "{\"CacheInsertDateTime\":\"\\/Date(1360761324878)\\/\",\"Data\":[{\"__type\":\"SomeObject:#ConsoleApplication1\",\"Symbol\":\"some object 1\"},{\"__type\":\"SomeObject:#ConsoleApplication1\",\"Symbol\":\"some object 2\"}]}";
byteData = Encoding.UTF8.GetBytes(jsonString);
using (MemoryStream stream = new MemoryStream(byteData))
{
var serializer = new DataContractJsonSerializer(typeof(CacheData));
obj = serializer.ReadObject(stream) as CacheData;
}
CacheResponse<List<SomeObject>> response2 = new CacheResponse<List<SomeObject>>();
response2.CacheData = obj;
List<SomeObject> responseList = response2.Data;//this is null
}
}
}
【问题讨论】:
-
我找不到如何附加 zip 文件
-
"数据来自 List 而不是 List" 数据来自 List
-
注意:对那些泛型类型使用反引号:`