1

我有以下示例 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>

这里有一个问题:为什么不能为 Animal 构造的 DataContractSerializer 反序列化第二个 xml?它抛出类似:从命名空间'bla bla'中期待元素'Animal'..遇到名称为'Dog'的'Element',命名空间'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 进行序列化(这似乎更合理,并且可能默认情况下应该存在)?

4

2 回答 2

4

在服务的接口上使用 ServiceKnownType,而不是在类 Animal 上。

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

public class Animals : IAnimals { [your original code] }
于 2013-07-03T20:13:51.243 回答
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 ,或者创建一个自定义的。

于 2013-02-12T13:56:32.080 回答