Adding root xmlns using XmlSerializer with WCF SOAP

I have a class file generated from an XML Schema document provided by our client by a third party. I have to use this generated class for the SOAP client web service, but I'm having some problems.

I created the ServiceContract interface, so I can use WCF ChannelFactory to connect to the web service, for example:

 [ServiceContract(Namespace = "http://theircompany.co.uk/theirapp/v1")] [XmlSerializerFormat] public interface IWebService { [OperationContract] EPSStatus serviceNotifyDataEventSet( [XmlElement(Namespace = "http://www.thirdparty.org/thirdapp")] DataEventSet dataSet ); } 

Both EPSStatus and DataEventSet are in my generated class file. Important bits of a DataEventSet :

 [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.thirdparty.org/thirdapp")] [System.Xml.Serialization.XmlRootAttribute(Namespace="http://www.thirdparty.org/thirdapp", IsNullable=false)] public partial class DataEventSet { //... } 

When I try to call IWebService.serviceNotifyDataEventSet , I get the following SOAP module (with WCF tracing enabled on my server):

 <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <serviceNotifyDataEventSet xmlns="http://theircompany.co.uk/theirapp/v1"> <dataSet> <dataEvents xsi:type="q1:DAInt" xmlns="" xmlns:q1="http://www.thirdparty.org/thirdapp"> <id>47245361157</id> <time> <tick_time>141728877218</tick_time> <time>2012-06-28T10:07:57.218+01:00</time> <time_type>OSACBM_TIME_MIMOSA</time_type> </time> <value>42</value> </dataEvents> <id xmlns="">0</id> <site xmlns=""> <category>SITE_SPECIFIC</category> </site> <time xmlns=""> <tick_time>141728877218</tick_time> <time>2012-06-28T10:07:57.218+01:00</time> <time_type>OSACBM_TIME_MIMOSA</time_type> </time> </dataSet> </serviceNotifyDataEventSet> </s:Body> 

So, I can call the web service, and it seems that my data is being correctly serialized, however, on the server side the dataSet is zero. I also received a trace from a client that works with the following body:

 <soap:Body> <serviceNotifyDataEventSet xmlns="http://theircompany.co.uk/theirapp/v1"> <dataSet xmlns="http://www.thirdparty.org/thirdapp"> <dataEvents xmlns:q1="http://www.thirdparty.org/thirdapp" xsi:type="q1:DAReal" xmlns=""> <id>47245361408</id> <time> <tick_time>141730618844</tick_time> <time>2012-06-28T10:36:58.843+01:00</time> <time_type>OSACBM_TIME_MIMOSA</time_type> </time> <value>12.34</value> </dataEvents> <id xmlns="">0</id> <site xmlns=""> <category>SITE_SPECIFIC</category> </site> <time xmlns=""> <tick_time>141730618843</tick_time> <time>2012-06-28T10:36:58.843+01:00</time> <time_type>OSACBM_TIME_MIMOSA</time_type> </time> </dataSet> </serviceNotifyDataEventSet> </soap:Body> 

The only difference that I see is that the root namespace is set to dataSet in the work package: <dataSet xmlns="http://www.thirdparty.org/thirdapp"> . In my package, the namespace is not specified at all.

My question is, does my analysis sound reasonable, and if so, how can I get the root xmlns for the correct output on my dataSet ?

+4
source share
2 answers

Now I managed to get this to work using a relatively simple approach. Fortunately, code created using xsd XML Schemas marks all classes as partial without constructors. I added my own partial class to define a default constructor that overrides namespaces, as shown below:

 public partial class DataEventSet { [XmlNamespaceDeclarations] public XmlSerializerNamespaces _xmlns; /// <summary> /// Constructor for DataEventSet that sets up default namespaces /// </summary> public DataEventSet() { _xmlns = new XmlSerializerNamespaces(); _xmlns.Add("", "http://www.thirdparty.org/thirdapp"); _xmlns.Add("o", "http://www.thirdparty.org/thirdapp"); } } 

Now it is serialized as follows:

 <?xml version="1.0" encoding="utf-8"?> <s:Body xmlns:s="http://www.w3.org/2003/05/soap-envelope"> <serviceNotifyDataEventSet xmlns="http://theircompany.co.uk/theirapp/v1"> <dataSet xmlns="http://www.thirdparty.org/thirdapp" xmlns:o="http://www.thirdparty.org/thirdapp"> <dataEvents xsi:type="o:DABool" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <id>47245361157</id> <value>true</value> </dataEvents> <id xmlns="">0</id> <site xmlns=""> <category>SITE_SPECIFIC</category> </site> <time xmlns=""> <tick_time>396106152171</tick_time> <time>2012-07-20T13:29:12.171Z</time> <time_type>OSACBM_TIME_MIMOSA</time_type> </time> </dataSet> </serviceNotifyDataEventSet> </s:Body> 
+1
source

Your analysis sounds reasonable. When looking at the code you posted, I ask if the DataEventSet class is a class that you should consider regarding the <dataSet> element. Using System.Xml.Serialization.XmlRootAttribute should allow you to define / apply the correct namespace for the element. I assume that you need this attribute for another class to make the <dataSet> element correct.

0
source

All Articles