【问题标题】:For WCF, when is it necessary to statically tell a serializer about a data type?对于 WCF,什么时候需要静态地告诉序列化器一个数据类型?
【发布时间】:2010-01-08 16:03:39
【问题描述】:

我正在使用 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 注释所有内容?

【问题讨论】:

    标签: c# asp.net-mvc wcf json serialization


    【解决方案1】:

    我已经编辑了我之前的答案,因为我刚刚意识到这里的问题。

    我认为问题在于被序列化的类型是泛型的,您必须将任何泛型参数类型添加到 DataContractJsonSerializer 的已知类型中。

    如果我是对的,那么你仍然可以在没有注释的情况下这样做。

    首先,调用 DataContractJsonSerializer 上的构造函数,该构造函数接受 TypeIEnumerable<Type>

    然后将您构造序列化程序的方式更改为如下所示:

    DataContractJsonSerializer serializer = null;
    Type dataType = Data.GetType();
    if(dataType.IsGenericType)
        serializer = new DataContractJsonSerializer(dataType, dataType.GetGenericArguments());
    else
        serializer = new DataContractJsonSerializer(dataType);
    

    这将是我的下一步。

    【讨论】:

    • 虽然我觉得序列化程序不自己做这件事很荒谬,但你是对的。
    • 抱歉,您的评论可能是基于我原来的答案,我认为这个答案稍微宽泛(尽管在这种情况下它会起作用)。从那以后,我改变了我的答案,以提供我希望的更有弹性的解决方案,它也不需要您提前注释所有内容。 KnownTypes 是 WCF 序列化的一个问题,但它们存在是因为与标准序列化不同,整个类型信息没有持久化(使 XML/Json 更具可读性和合规性)。
    • 哦,您也编辑了您的评论!我试图再次编辑我的,但错过了时间限制。底线 - 你是对的;虽然在许多情况下需要 KnownTypes 是有道理的,但在这种特殊情况下,WCF 团队对构造函数代码进行微小改动以处理泛型可以解决所有这些问题。很高兴它起作用了,无论如何:)
    【解决方案2】:

    由于 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);
    

    很简单

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      • 2019-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-15
      相关资源
      最近更新 更多