wcf服务返回派生类型

时间:2013-02-12 11:02:25

标签: c# .net wcf datacontractserializer

我有以下示例wcf服务(使用webHttpBinding):

[ServiceContract]
public class Animals {

    [OperationContract]
    [WebGet(UriTemplate = "/{id}")]
    [ServiceKnownType(typeof(Dog))]
    public Animal GetAnimalById(string id) {
        switch (id) {
            case "1": return new Animal { Id = 1 };
            case "2": return new Dog { Id = 2 };
        }
        throw new ArgumentException();
    }
}

类型定义如下:

[DataContract]
[KnownType(typeof(Dog))]
public class Animal {
    [DataMember]
    public int Id { get; set; } 
}

public class Dog : Animal {
    [DataMember]
    public string Name { get; set; }
}

当提供1时,从服务中撤回的xml是(为简洁起见,省略了xmlns):

<Animal><Id>1</Id><Name i:nil="true"/></Animal>

提供2时:

<Dog><Id>2</Id><Name i:nil="true"/></Dog>

以下是问题:为什么DataContractSerializer不能为Animal反序列化第二个xml?它会抛出类似于:命名空间'bla bla'中的元素'Animal'。遇到'Element'名为'Dog',命名空间'bla bla'。

其他信息:
 1.如果构造DataContractSerializer提供typeof(Dog)作为参数,它显然有用  2.如果我构造DataContractSerializer提供typeof(Animal)作为参数(因为我不知道我将要序列化/反序列化的对象类型)然后序列化Dog xml将如下所示:

<Animal i:type="Dog"><Id>0</Id><Name i:nil="true"/></Animal>

反过来可以使用相同的序列化程序反序列化而没有任何问题。我可以强制WCF使用随基类型提供的DataContractSerializer进行序列化而不是派生(这似乎更合理,并且可能默认应该在那里)?

2 个答案:

答案 0 :(得分:4)

使用服务的接口上的ServiceKnownType代替Animal类。

[ServiceKnownType(typeof(Dog))]
[ServiceContract]
public interface IAnimals 
{
  public Animal GetAnimalById(string id);
}

public class Animals : IAnimals { [your original code] }

答案 1 :(得分:1)

因为WCF传递的是结构化XML数据,而不是类型。 WCF不是面向对象的。见http://msdn.microsoft.com/en-us/library/ms751512.aspx

如果您愿意,可以使用http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx,或创建自定义的。{/ p>