A note up front: I cannot change the format of the SOAP requests coming in, as they are fixed by international standards (weeeeeeeee).
I have a SOAP request that comes into my WCF service looking something like this:
<s:Body>
<Request version="1.0">
<data someOtherVersion="1.1">
...
</data>
</Request>
</s:Body>
Up to now, we've been using System.ServiceModel.Channels.Message
objects directly, which is kind of a pain. We're trying to move to using strong types that look like this:
[MessageContract(IsWrapped = false)]
public class Request
{
[MessageBodyMember]
[XmlAttribute("version")]
public string Version;
[MessageBodyMember]
[XmlElement("data")]
public SomeOtherType Data;
}
[MessageContract(IsWrapped = false)]
public class Response
{
[MessageBodyMember]
[XmlAttribute("version")]
public string Version;
[MessageBodyMember]
[XmlElement("data")]
public SomeOtherType ResponseData;
}
[ServiceContract]
[XmlSerializerFormat]
public interface Service
{
[OperationContract(Action = "request", ReplyAction = "response")]
Response ServiceOperation(Request req);
}
Unfortunately, when we try to start up, we get an error saying "An unhandled exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.dll
Additional information: XmlSerializer attribute System.Xml.Serialization.XmlAttributeAttribute is not valid in Version. Only XmlElement, XmlArray, XmlArrayItem and XmlAnyElement attributes are supported in MessageContract when IsWrapped is false."
Interestingly, setting "IsWrapped" to true gives the same error. Is there a way to serialize XML attributes in message contract types, or is using wrappers our only option here?
Unfortunately the only way I found to achieve this is to use a wrapper class
[MessageContract(IsWrapped = false)]
public class Response
{
[MessageBodyMember(Name = "Response", Namespace = "Http://example.org/ns1")]
public ResponseBody Body { get; set; }
public Response(){}
public Response(ResponseBody body)
{
Body = body;
}
}
[XmlType(AnonymousType = true, Namespace = "Http://example.org/ns1")]
public class ResponseBody
{
[XmlAttribute(AttributeName = "version")]
public string Version { get; set; }
[XmlElement(ElementName = "data", Namespace = "Http://example.org/ns1")]
[MessageBodyMember]
public SomeOtherType ResponseData { get; set; }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With