Веб-сервисы - XmlInclude в производном классе вместо базового класса? - PullRequest
1 голос
/ 12 июня 2009

Я использую абстрактный класс в качестве параметра в вызове веб-службы. В настоящее время я включаю XmlInclude производного класса в базовый класс, например:

[XmlInclude(typeof(DerivedClass))]
public abstract class BaseClass
{
}

Однако я бы предпочел не включать все производные типы в базовый класс.

В http://www.pluralsight.com/community/blogs/craig/archive/2004/07/08/1580.aspx, автор упоминает альтернативу - вместо этого записывает атрибут над веб-методом, например:

[WebMethod]
[System.Xml.Serialization.XmlInclude(typeof(DerivedClass))]
public BaseClass getClass() {
     return new DerivedClass(); 
}

Однако я также не хотел бы помещать производные типы в веб-сервис. Есть ли способ сохранить атрибут в производном типе?

Ответы [ 2 ]

4 голосов
/ 13 июня 2009

Предположим, что фреймворк каким-то образом должен знать, какие типы находятся в типе hiearchy, когда происходит десериализация, и как эти типы представлены в xml. На самом деле нет никакой возможности вывести эту информацию, если она хранится в производном типе.

У вас есть несколько вариантов: - используйте атрибут XmlInclude - указать набор разрешенных типов в перегрузке конструктора XmlSerializer

Теперь, если вы ожидаете, что подкласс будет передан веб-службе, веб-сервер контролирует сериализацию и десериализацию. Таким образом, конструктор XmlSerializer больше не является опцией.

Как вы говорите, вы можете поместить атрибут в метод веб-службы, а не непосредственно в класс. Существует компромисс между сохранением вашего класса "чистым" и не забыванием размещать эти атрибуты в каждом месте, где они могут потребоваться.

Конечно, реальная проблема заключается в том, что вы пытаетесь использовать свои бизнес-объекты в качестве формата сообщений на уровне веб-сервиса.

Если вы действительно хотите разделить обязанности «формат сообщения» и «бизнес-объект», то используйте другой класс (с полной иерархией), для которого единственное использование должно использоваться в качестве параметра веб-службы. В этом случае нет проблем с прикреплением всех необходимых атрибутов XmlInclude к базовому классу. Затем, при обращении к веб-сервису, адаптируйте свой бизнес-объект к объекту формата сообщения и обратно. Это дает вам дополнительное преимущество в том, что вы не применяете ограничения типов веб-сервисов к типам ваших параметров (например, нет интерфейсов в качестве параметров).

Конечно, этот метод не так удобен.

В конце концов, веб-сервису нужно знать, какие типы ожидать, или он не сможет правильно их сериализовать и десериализовать.

И да, это длинное многословное объяснение того, почему ответ - нет, вы не можете только сохранить атрибут в производном типе. Я хотел бы быть неправ, хотя:)

2 голосов
/ 13 июня 2009

Я не вижу, как в этом случае. При десериализации существует перегрузка для массива дополнительных типов, в который вы передаете производные типы.

...