将用户定义的类定义为DataContract

时间:2012-02-18 23:37:54

标签: jquery ajax wcf

我想使用AJAX调用来使用WCF REST服务。

假设我有以下Person是用户定义的类:

[ServiceContract]
public interface IPerson
{
    [WebInvoke(ResponseFormat = WebMessageFormat.Json)]   
    [OperationContract]
    Person GetPerson();
}

Person定义为DataContract和将Person定义为DataContract之间有何区别?

[DataContract]
public class Person
{
    [DataMember]
    public string FirstName { get; set; }

    [DataMember]
    public string LastName { get; set; }
}

在客户端,无论Person是否定义为DataContract,我都可以使用以下内容,对吧?

<script type="text/javascript">
    $().ready(function() {
        $("#Button1").click(function() {
            $.getJSON("<url of the service>/GetPerson", CallBackMethod);
        });
    });

    function CallBackMethod(result) {
        alert(result.FirstName);
        alert(result.LastName);
    }
</script>

2 个答案:

答案 0 :(得分:2)

数据协定只是.NET Framework支持的一种序列化形式;它们本质上是WCF前XML序列化的替代品。这一切都是通过DataContractSerializer完成的,DataContractSerializer负责将您的对象转换为与数据协定匹配的序列化XML。这是WCF和ASP.NET JSON代码使用的序列化程序类,以及其他方面。

理论上,您应该使用DataContract和DataMember属性标记合同对象,以明确它们的用途。实际上,DataContractSerializer将根据您提供的任何自定义类型生成数据协定;如果您将它们关闭,它将为您推断出DataContract和DataMember属性。通过添加它们,您可以更好地控制序列化的工作方式,这与添加XML序列化属性的方式完全相同。由于缺少显式属性,对象中的所有公共字段都将成为数据协定的一部分。

所以,你的问题的真正答案是Person 总是定义为DataContract,至少就序列化器而言;将属性添加到您的类及其所有公共成员将产生相同的效果。 IMO,没有充分理由这样做:它会花费你几毫秒的打字时间,如果不这样做,运行时只会假装你做了。

答案 1 :(得分:1)

首先,在某些情况下,类型可以实现多个编程模型。例如,它可以是DataContract和IXmlSerializable,也可以是CollectionDataContract和IXmlSerializable。数据契约编程模型 - 不仅仅是DataContractAttribute - 决定了这些类型应该如何序列化。有关其工作原理的详细信息,请参阅the awesome blog post here

要回答您的具体问题,在.NET 3.5 SP1之前,您无法序列化“POCO”类型(普通的旧C#类型),除非它们使用DataContractAttribute进行修饰。然而,一旦引入POCO支持,它就没有任何区别。有关详细信息,请参阅this blog post

希望这有帮助!