WCF和DataContractSerializer是否以不同方式序列化CollectionDataContract修饰的集合类型?

时间:2010-11-30 19:15:11

标签: wcf datacontractserializer

我有一个非常简单的自定义集合类型,它继承自List<>并使用CollectionDataContract。

当我使用DataContractSerializer.WriteObject对其进行序列化时,它会按照我期望的方式尊重CollectionDataContract属性;但是,当我将它用作WCF方法的返回类型时,我得到了默认的ArrayOfFoo。

我想知道服务合同中是否有一些装饰。

详细说明:

[DataContract(Namespace = "")]
public class Foo
{
    [DataMember]
    public string BarString { get; set; }
}

[CollectionDataContract(Namespace = "")]
[Serializable]
public class FooList : List<Foo> {}

如果我只是实例化Foo然后使用DataContractSerializer.WriteObject来序列化它,我会得到你所期望的:

<FooList>
    <Foo>
        <BarString>myString1</BarString>
    </Foo>
</FooList>

但是,如果我有一个像这样的方法的服务......

[ServiceContract Name = "MyService"]
public interface IMyService
{
    [OperationContract, WebGet(UriTemplate = "foos/")]
    FooList GetAllFoos();
}

然后为http://www.someEndpoint.com/foos/做一个GET,我明白了:

<ArrayOfFoo>
    <Foo>
        <BarString>myString1</BarString>
    </Foo>
</ArrayOfFoo>

我也尝试在CollectionDataContract属性中指定Name =“MyFooListName”。相同的结果:DataContractSerializer获取备忘录; WCF没有。

3 个答案:

答案 0 :(得分:3)

Saeed向我发出了正确的方向:当我一直希望使用DataContractSerializer时,我无意中最终得到了XmlSerializer。

我最终得到了XmlSerializer ......好吧......通过要求它。

特别是,我使用XmlSerializerFormat在我的服务中修饰了这样的方法:

[ServiceContract Name = "MyService"] 
public interface IMyService 
{ 
    //  ... other stuff ...

    [OperationContract, WebInvoke(UriTemplate = "foos/", Method = "POST")] 
    [XmlSerializerFormat]
    Foo PostAFoo(Foo yourNewFoo);
} 

我之所以这样做是为了希望在手工制作的Foo XML blob中使用宽松的成员顺序。当然,当一个人这样做时,最终会得到XmlSerializer,而不是DataContractSerializer。

当我拿走XmlSerializerFormat属性时,问题解决了:WCF现在按照我想要的方式序列化我的FooList集合。

答案 1 :(得分:2)

有关详细信息,请参阅MSDN

  

DataContractSerializer没有   支持使用的编程模型   XmlSerializer和ASP.NET Web   服务。特别是,它没有   支持属性,如   XmlElementAttribute和   XmlAttributeAttribute。启用   支持这种编程模型,   必须切换WCF才能使用   XmlSerializer而不是   DataContractSerializer的。

因此序列化将由XMLSerializer完成,您无法更改它。

答案 2 :(得分:0)

您在配置WCF服务时是否选择了通用类型?如果没有,

右键单击并转到配置,然后选择Generic Type,默认情况下它是arraylist类型。