Как проанализировать soap xml-сообщение, которое передается в мою операцию службы wcf?

#c# #wcf #soap

#c# #wcf #soap

Вопрос:

У меня есть следующий запрос Soap, который я получаю от клиента, где в основном я должен извлечь имя, а затем отправить обратно «Приветственный тест»

 <?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"   
xmlns:ns1="http://tempuri.org/">
<SOAP-ENV:Body>
    <ns1:Customer>
    <ns1:Name>Test</ns1:Name>
    </ns1:Customer>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
  

Если у меня есть класс, который клиент определяет следующим образом:

 public class Customer
{
    public string Name {get;set;}
}
  

Я не уверен, как передать запрос soap в мою операцию службы wcf, которая примет объект запроса клиента, сгенерированный из xsd?

После того, как моя операция службы wcf получит запрос soap, я не уверен, как извлечь из него атрибут Name и отправить ответ обратно клиенту, например, возможно, «Hello Test»

Примечание: Клиент не собирается отправлять объект Customer, он собирается отправить xml-запрос, и я должен проанализировать его в объект Customer. Я надеюсь, что это прояснит ситуацию.

Должен ли я делать что-то подобное, когда я передаю XDocument в свою служебную операцию wcf:

 private static void ParsSoapDocument(XDocument soapDocument)
{
   //Parse XDocument for elements/attributes

}
  

Ответ №1:

Вам не нужно ничего разбирать, это то, что WCF обрабатывает за вас.

Могут быть варианты, основанные на том, используете ли вы завернутые / развернутые сообщения, но базовый сценарий для сообщения soap, которое вы описываете, поступающего от клиента, интерфейс вашей службы будет следующим (при условии, что ваш ответ — string ):

 [ServiceContract]
public interface IMyService
{
    [OperationContract]
    public string Customer(string Name);
}
  

Скорее всего, вы на самом деле пытаетесь выполнить операцию, которая принимает клиента. Например, чтобы проверить, существует ли клиент, вы могли бы:

 [ServiceContract]
public interface IMyService
{
    [OperationContract]
    public bool CheckCustomerExists(Customer Customer);
}
  

и ваш Customer класс на стороне службы должен быть определен как DataContract :

 [DataContract]
public class Customer
{
    public string Name{get;set;}
}
  

Это сделало бы запрос soap следующим:

 <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/"> <SOAP-ENV:Body>
    <ns1:CheckCustomerExists>
    <ns1:Customer>
    <ns1:Name>Test</ns1:Name>
    </ns1:Customer>
    </ns1:CheckCustomerExists> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
  

Комментарии:

1. Итан, спасибо за это. У меня есть клиенты, которые отправляют мне запросы, поэтому я не контролирую запрос, я просто контролирую, что я делаю, когда получаю запрос, например, добавление клиента в базу данных. Вы знаете, как я могу просмотреть запрос / ответ soap в .net (например, — с помощью консоли. Строка записи (…))

2. @john Я упоминаю использование MessageContract в двух местах, поэтому не совсем уверен, о каком из них вы спрашиваете. Во-первых, я упомянул, что вам нужно было бы использовать MessageContract , если бы операция использовала объект Customer, а не простой тип данных. Я полагаю, вы также могли бы использовать, DataContract но я обычно использую сообщения (которые попадают по второй MessageContract ссылке). Во-вторых, я предлагаю использовать запрос / ответ, если op контролирует дизайн сообщения и если сообщения будут довольно сложными.

3. @Xaisoft — Для просмотра SOAP, отправляемого по проводам, вы можете использовать Fiddler. Вы также можете вызвать службу с помощью SoapUI, которая покажет вам необработанный ответ. Оба эти хороших (и бесплатных) инструмента можно добавить в свой арсенал. Существует также возможность ведения журнала, которую можно легко включить / выключить с помощью редактора конфигурации службы WCF, но с выводом может быть немного сложно работать, если вы новичок (или эксперт …)

4. @Ethan: MessageContract это необходимо только в том случае, если у вас есть несколько частей тела и / или заголовка. В противном случае, DataContract это то, что следует использовать.

5. @John — ты прав. DataContract это все, что нужно. Что касается моего заключительного комментария, я по-прежнему выступаю за подход, основанный на сообщениях, если служебные операции усложняются, но сообщения могут быть определены с помощью DataContract , если не требуется больший контроль над структурой SOAP (например, добавление полей в заголовок). Я все еще думаю, что -1 немного сурово, хотя, учитывая, что я ответил на вопрос ops 🙂 Учит меня добавлять дополнительную информацию.