Как настроить сериализацию WCF XML - PullRequest
8 голосов
/ 16 марта 2009

У нас есть существующий интерфейс веб-службы SOAP, который мы хотим реализовать, используя WCF для нового приложения. Это, кажется, работает хорошо, за исключением одной маленькой детали. Пространство имен XML возвращаемого типа функции должно отличаться от пространства имен XML самого веб-сервиса. И ради жизни я не могу заставить его работать.

Я воссоздал ту же проблему с небольшим примером проекта. Интерфейс WCF:

[XmlSerializerFormat]
[ServiceContract(Namespace = "urn:outer-namespace")]
public interface IService1
{
    [OperationContract]
    MyClass DoStuff(int value);
}

[Serializable]
public class MyClass
{
    [XmlElement(ElementName = "DataString")]
    public string MyString { get; set; }
}

Реализация веб-сервиса:

    public class Service1 : IService1
{
    public MyClass DoStuff(int value)
    {
        return new MyClass { MyString = "Wooh!" };
    }
}

Ответ от этого веб-сервиса затем сериализуется как: (Опуская SOAP материал)

  <DoStuffResponse xmlns="urn:outer-namespace">
     <DoStuffResult>
        <DataString>Wooh!</DataString>
     </DoStuffResult>
  </DoStuffResponse>

Но мы хотим, чтобы был xmlns = "urn: inner-namespace".

Я пытался добавить [return: XmlElement (...)] в функцию интерфейса или функцию веб-службы, но это не требует. Также [XmlType] или [XmlRoot] в определении класса MyClass не работает.

Кто-нибудь знает, как изменить сериализованное пространство имен XML (или имя элемента) объекта, которое является возвращаемым значением функции веб-службы WCF?

Ответы [ 2 ]

3 голосов
/ 16 марта 2009

Определение пространств имен с помощью атрибутов определения контракта данных XML (или, что лучше,).

например. с сериализацией XML:

[Serializable, XmlRoot(namespace="http://example.com/eg1")]
public class MyClass {
  [XmlElement(ElementName = "DataString")]
  public string MyString { get; set; }
}

например. с сериализацией контракта данных:

[DataContract(Namespace="http://example.com/eg2")]
public class MyClass {
  [DataMember]
  public string MyString { get; set; }
}

EDIT

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

OperationContractAttribute не предоставляет контроля над пространствами имен, и я не вижу никаких других атрибутов WCF на уровне метода.

Две возможности: (1) Вы можете иметь достаточный контроль, отбрасывая уровень абстракции и используя Контракт сообщения. (2) Получите текущий WSDL для службы (используя svcutil.exe), вручную измените его, чтобы получить нужные пространства имен, а затем снова используйте svcutil.exe для генерации кода и посмотрите на полученный код.

1 голос
/ 20 марта 2017

После нескольких дней поиска и проб десятки рекомендуемых решений; Наконец-то я смог заставить WCF прекратить форсировать имя контейнера-оболочки, добавляя Result к имени метода веб-службы. Хитрость заключалась в том, чтобы добавить следующий атрибут декоратора в интерфейс веб-службы:

[return:MessageParameter(Name = "whatIWantItNamed")]

Этот атрибут должен быть расположен / расположен непосредственно после атрибута [OperationContract] (и непосредственно перед фактической заглушкой метода) в интерфейсе.

(мне также нужно было добавить атрибут XmlSerializerFormat ко всем атрибутам ServiceContract и OperationContract.)

...