Веб-сервисы - 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 к базовому классу. Затем, при обращении к веб-службе, адаптируйте свой бизнес-объект к объекту формата сообщения и обратно. Это дает вам дополнительное преимущество в том, что вы не применяете ограничения типов веб-сервисов к типам ваших параметров (например, нет интерфейсов в качестве параметров).
Конечно, этот метод не так удобен.
В конце концов, веб-сервису нужно знать, каких типов ожидать, иначе он не сможет правильно их сериализовать и десериализовать.
И да, это длинное объяснение того, почему ответ "нет", вы не можете только сохранить атрибут в производном типе. Я хотел бы быть неправ, хотя:)
Я не вижу, как в этом случае. При десериализации существует перегрузка для указания массива дополнительных типов, в который вы передаете производные типы.