Mike
Mike

Reputation: 834

Getting SOAP messages with a specific schema in .NET

I am writing a service in .NET that receives XML objects in a SOAP envelope that will take that message and response with a SOAP message using the same schema. For example:

Request:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body xmlns="http://schemas.mystuff.org/myschema">
    <Message>
      <Header>...</Header>
      <MessageContent>...</MessageContent>
    </Message>
  </s:Body>
</s:Envelope>

Response:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body xmlns="http://schemas.mystuff.org/myschema">
    <Message>
      <Header>...</Header>
      <MessageContent>...</MessageContent>
    </Message>
  </s:Body>
</s:Envelope>

Also, I would like to end up not with a hierarchy of objects, but just the string of the XML.

When I use WCF ServiceContracts to do this then WCF defines an extra layer of wrappers for the WSDL service it generated, for example:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <SendMessageResponse xmlns="http://tempuri.org/">
      <SendMessageResult xmlns:a="http://schemas.datacontract.org/2004/07/CxMessageReceiverRole" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:Message>
          ...
        </a:Message>
      </SendMessageResult>
    </SendMessageResponse>
  </s:Body>
</s:Envelope>

What is the best way for me to receive and send SOAP messages in .NET where I am controlling what the messages look like rather than WCF? It doesn't have to be WCF if that's not the best way. Also, I don't want to implement an entire class structure to represent my XML schema, but instead just receive the SOAP body as a string.

Upvotes: 0

Views: 1730

Answers (1)

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364249

First you can't receive SOAP body as string if you do not send string. You can only get XML but in such case your autogenerated WSDL will doesn't contain description of your body format. It will only define xsd:any which means any well formed XML.

When you don't want to have wrapping element you have to use MessageContract instead of DataContract. DataContracts always use default wrapping elements based on operation name. MessageContracts overrides this behavior and defines top level element.

I suggest something like this:

[MessageContract]
public class Message
{
  [MessageBodyMember]
  public XElement Header { get; set; }
  [MessageBodyMember]
  public XElement MessageContent { get; set; }
}

Other approach is using System.ServiceModel.Channels.Message class and read content from the message manually.

Upvotes: 1

Related Questions