2013-02-12 4 views
0

У меня есть следующие службы образца ФОС (с использованием 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-retured от обслуживание (XMLNS опущены для краткости):

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

Когда 2 подается:

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

И вот вопрос: Почему DataContractSerializer не построен для животных десериализации второй XML? Это бросает что-то вроде: Ожидающий элемент «Животное» из пространства имен «бла-бла». Обнаруженный «Элемент» с именем «Собака», пространство имен «бла-бла».

Дополнительная информация:
1. Если я создаю DataContractSerializer, поставляющий typeof (Dog) в качестве параметра, он, очевидно, работает.
2. Если я построить DataContractSerializer поставляя TYPEOF (Animal) в качестве параметра (потому что я не знаю, тип объекта, я собираюсь сериализации/десериализации), а затем сериализации Dog XML, будет выглядеть следующим образом:

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

Который, в свою очередь, может быть десериализован с использованием одного и того же сериализатора без каких-либо проблем. Могу ли я заставить WCF сериализоваться с использованием DataContractSerializer, поставляемого с базовым типом, а не с производным (что кажется более разумным и, вероятно, должно быть по умолчанию в любом случае)?

ответ

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, если хотите, или создать собственный.

+0

Я не уверен, что вы заметили @Jocke, но я применить KnownType к классу собак, и он работает, он получает сериализовать (но, как собака, а не как который будет иметь больше смысла при подписи службы). Что касается второй ссылки, которую вы отправляете, я хочу использовать DataContractSerializer. – Adam

3

Используйте СервисKnownType на интерфейсе вашей службы вместо этого на классе Animal.

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

public class Animals : IAnimals { [your original code] } 
Смежные вопросы