Сериализация XML - отсутствует префикс пространства имен на стороне клиента - PullRequest
4 голосов
/ 20 марта 2009

Я создал веб-сервис .NET, который возвращает объект, скажем, класс "getResponse".

WS возвращает следующий ответ ...

<getResponse xmlns="http://tempuri.org/getCustomer/wsdl/">
   <Result xmlns="http://tempuri.org/getCustomer/">
      <ResultCode>OK</ResultCode>
      <ErrorsList/>
   </Result>  
</getResponse>

пока клиент фактически ожидает следующего ... (обратите внимание на префикс mes-root:)

<mes-root:getResponse xsi:schemaLocation="http://tempuri.org/getCustomer/ getCustomer_V200906.xsd" xmlns:mes-root="http://tempuri.org/getCustomer/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <mes-root:Result>
  <mes-root:ResultCode/>
  <mes-root:ErrorsList/>
 </mes-root:Result>
</mes-root:getResponse>

Как мне это сделать? Нужно ли устанавливать определенные атрибуты XML-сериализации в классе getResponse, чтобы префикс mes-root отображался на стороне клиента?

РЕДАКТИРОВАТЬ: Я нашел похожий вопрос в следующем месте http://forums.asp.net/t/1249049.aspx. Если честно, я не совсем понимаю, и я не могу заставить его работать.

Ответы [ 2 ]

10 голосов
/ 21 марта 2009

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

Чтобы решить проблему с префиксом пространства имен, ссылка, которую вы указали в своем вопросе, обеспечивает соответствующее решение; Вам нужно будет «направлять» XmlSerializer во время процесса сериализации, и вы можете сделать это, указав атрибут XmlNamespaceDeclarations для свойства, которое возвращает объект типа XmlSerializerNamespaces. Это свойство также необходимо будет установить, иначе пространства имен не будут применены.

Когда вы добавляете следующий код в класс getResponse, ответ xml будет соответствовать ожидаемому формату в вашем примере:

[XmlNamespaceDeclarations()] 
public XmlSerializerNamespaces xmlsn 
{ 
  get 
  { 
    XmlSerializerNamespaces xsn = new XmlSerializerNamespaces(); 
    xsn.Add("mes-root", "http://tempuri.org/getCustomer/"); 
    return xsn; 
  } 
  set 
  {
  //Just provide an empty setter. 
  } 
} 

Анализ класса WSDL, сгенерированного для такого веб-сервиса, показывает следующий метод («GetMyResponse» - это имя, которое я дал методу WS, который возвращает объект GetResponse):

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/getCustomer/GetMyResponse", RequestNamespace = "http://tempuri.org/getCustomer/", ResponseNamespace = "http://tempuri.org/getCustomer/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] 
public GetResponse GetMyResponse() 
{ 
  object[] results = this.Invoke("GetMyResponse", new object[-1 + 1]); 
  return (GetResponse)results(0); 
}

Я считаю, что атрибуты RequestNamespace и ResponseNamespace имеют значение.

Надеюсь, что это прояснит некоторые проблемы в понимании лежащей здесь XML-сериализации.

Редактировать (после комментариев)


Вот ответ, который я получил через мой тестовый веб-сервис:

<?xml version="1.0" encoding="utf-8"?>
<mes-root:GetResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:mes-root="http://tempuri.org/getCustomer/">
  <mes-root:Result>OK</mes-root:Result>
  <mes-root:ErrorsList>
    <mes-root:string>SomeErrors</mes-root:string>
    <mes-root:string>SomeMoreErrors</mes-root:string>
  </mes-root:ErrorsList>
</mes-root:GetResponse>
1 голос
/ 20 марта 2009

ОК, второй пример теперь является допустимым XML, но он семантически не эквивалентен первому примеру, поскольку первый имеет два пространства имен, а второй - только одно.

Является ли проблема, что вы отправляете XML, который не является семантически правильным, или что они специально требуют, чтобы префикс был назван mes-root?

...