我正在使用WCF JSON序列化程序生成JSON,以用作ASP.NET MVC框架的返回数据。我这样做是因为内置的JsonAction没有提供任何方法来控制序列化JSON中公共属性的命名。
public override void ExecuteResult(ControllerContext context)
{
...
if (Data != null)
{
var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(Data.GetType());
System.IO.MemoryStream ms = new System.IO.MemoryStream();
serializer.WriteObject(ms, this.Data);
response.Write(Encoding.Default.GetString(ms.ToArray()));
}
}
在这个例子中,我在OpenFlashChart中使用它,所以我将this.Data设置为PieChart实例。它工作正常。然后,我将this.Data设置为Chart的实例,我得到以下异常:
Type 'OpenFlashChart.Pie' with data contract name 'Pie:http://schemas.datacontract.org/2004/07/OpenFlashChart' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
显然,当我给序列化程序一个PieChart
元素时,它能够推断出我也需要Pie类。为什么我提供它Chart<PieChart>
时,是否不再查看PieChart
使用的类?有没有办法解决这个问题,而无需用KnownTypeAttributes
注释所有内容?
答案 0 :(得分:1)
我编辑了之前的答案,因为我刚刚意识到这个问题。
我认为问题是因为被序列化的类型是通用的,你必须将任何通用参数类型添加到DataContractJsonSerializer的已知类型。
如果我是对的,那么你仍然可以在没有注释的情况下这样做。
首先,在DataContractJsonSerializer上调用构造函数,该构造函数接受Type
和IEnumerable<Type>
。
然后将构建序列化器的方式更改为:
DataContractJsonSerializer serializer = null;
Type dataType = Data.GetType();
if(dataType.IsGenericType)
serializer = new DataContractJsonSerializer(dataType, dataType.GetGenericArguments());
else
serializer = new DataContractJsonSerializer(dataType);
这将是我的下一步。
答案 1 :(得分:0)
由于Andras的帖子最初是我在JSON序列化/反序列化方面实现的解决方案之一,并且自那以后发现了一种更好的方法(至少为我自己的目的),我想分享一下:
// Add a reference to System.Web.Extensions **(.NET 4.0 required)**
using System.Web.Script.Serialization;
...
// To serialize...
JavaScriptSerializer serializer = new JavaScriptSerializer();
String serializedData = serializer.Serialize(data);
// To deserialize...
deserializedData = serializer.Deserialize<data.GetType()>(serializedData);
// OR even
var anyObject = .serializer.Deserialize<dynamic>(serializedData);
很简单