收录日期:2020/12/02 22:52:29 时间:2010-09-07 20:16:30 标签:xml,wcf,messagecontract

I'm working with WCF, implementing a very (VERY) complex set of interactions (that we've been handed by a committee controlled by people who have never heard of computers) over SOAP. I will be receiving a message that looks like this:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
 <s:Header>
  ... (lots of "standard" stuff that noone has ever dared
       to cobble together in such non-standard ways before)
 </s:Header>
 <s:Body>
  <MyIncrediblyComplexXmlElement>
   ...
  </MyIncrediblyComplexXmlElement>
 </s:Body>
</s:Envelope>

... and I do NOT wish to parse the body content into an object model created by xsd.exe or svcutil.exe (whether or not those tools could even produce an object model that could successfully serialize/deserialize this particular XML is a matter of vigorous debate). I plan to create a Message Contract to implement these services, and I'm wondering if I can do something akin to the following:

[ServiceContract(Namespace = "mynamespace")]
public interface IMyServiceInterface
{
 [OperationContract(Action = "requestaction", ReplyAction = "replyaction")]
 MyResponseMessage MyMethod(MyRequestMessage request);
}

[MessageContract(IsWrapped = false)]
public class MyRequestMessage
{
 [MessageBodyMember(Namespace = "mynamespace", Order = 0)]
 public XmlElement MyIncrediblyComplexXmlElement { get; set; }
}

[MessageContract(IsWrapped = false)]
public class MyResponseMessage
{
 [MessageBodyMember(Namespace = "mynamespace", Order = 0)]
 public XmlElement SomeResponseXmlElement { get; set; }
}

... and then manipulate the XML directly that comes in and goes out in the request and response messages. This will greatly simplify development, since I have to work with only a small subset of the XML that could show up in the messages, and I can work with them more simply than the generated object model would allow.

Will this pattern (of using XmlElement in the Message Contracts) work for my purposes? If not, how can I accomplish the goal of working directly with the XML but without having to work with Message objects directly?

Working with XmlElement or XElement is possible. It will place xsd:any to generated message descriptions in WSDL. If you want to avoid serialization and deserialization to objects it is way to go but in that case any XML can arrive. Other possiblity is to work with Message type directly but you have already rejected it.

You can definitely write a Message inspector and plug that into the WCF runtime, in order to manipulate the message XML before it gets sent to the server, or when it gets received on the server side.

Check out the MSDN docs on Message Inspectors, or Pablo Pialorsi's blog post, for more tips. Things get quite messy and hairy at times - but the WCF runtime sure does offer you the necessary hooks. It it nice'n'easy? Probably not - but at least it's possible, and in a documented way, too!