我有一个非常简单的自定义集合类型,它继承自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没有。
答案 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类型。