Веб-сервисы - XmlInclude в производном классе вместо базового класса?

Я использую абстрактный класс в качестве параметра в вызове веб-службы. В настоящее время я включаю 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 ответа

Решение

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам