Question

How can you convert from a common object to web service object (same object but different namespace - the web service proxy changes the namespace), and from web service to common using Xml serialisation.

The code below has no exceptions, however the de-serialised object properties are set to their default values, rather than the values they should have. As @Mark Gravel points out in the answer below, this is because when you serialise to a web service object, it adds additional Xml namespaces. I've tried a number of approaches such as using Xml.Serialization.XmlSerializerNamespaces and setting the default namespace on serialisation, but I either got the same result or do something wrong and get an Xml error when de-serialising.

I realise this is slower (performance) than mapping the object properties directly, but it's quite large and I want to get a prototype running quickly without having to translate the object each time. Is there a way remove the namespaces altogether before de-serialising and adding adding the namespaces when serialising? - a structured way to add and remove the xmlns="http://[host.co.uk]/ bit.

Note, the web service are owned by third parties (so can't change that code), and the the object has no special Xml decorations. There are multiple web services involved so the namespaces will change at run time depending on the service URL.

To serialise I use this code:

Dim serializer As New Xml.Serialization.XmlSerializer(requestParams.GetType)
Using strWriter As New IO.StringWriter()
    serializer.Serialize(strWriter, requestParams)
    Return strWriter.ToString
End Using

To de-serialise I use this code:

Dim serializer As New XmlSerializer(GetType(T))
Using strReader As New IO.StringReader(serializedXml)
    Return DirectCast(serializer.Deserialize(strReader), T)
End Using

For reference, serialised common object:

<?xml version="1.0" encoding="utf-16"?>
<SearchPartsRequest>
  <LocationCode>01</LocationCode>
  <PartCriteria>
    <PartNo>1064762</PartNo>
  </PartCriteria>
  <WildCardSearch>false</WildCardSearch>
</SearchPartsRequest>

serialised web service object:

<?xml version="1.0" encoding="utf-16"?>
<SearchPartsRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <LocationCode xmlns="http://host.co.uk/">01</LocationCode>
  <PartCriteria xmlns="http://host.co.uk/">
    <PartNo>1064762</PartNo>
  </PartCriteria>
</SearchPartsRequest>
Was it helpful?

Solution 4

System.Xml.Serialization.XmlAttributes.Xmlns = False is the key.

Here is an example:

Dim atts As New System.Xml.Serialization.XmlAttributes()
' Set to true to preserve namespaces, or false to ignore them.
atts.Xmlns = False

Dim xover As New System.Xml.Serialization.XmlAttributeOverrides()
' Add the XmlAttributes and specify the name of  
' the element containing namespaces.
xover.Add(secCred.GetType, String.Empty, atts)

Dim serializer As New System.Xml.Serialization.XmlSerializer(secCred.GetType, xover)
Using strWriter As New IO.StringWriter()
    serializer.Serialize(strWriter, secCred)
    xml = strWriter.ToString
End Using

the string xml will contain (note the xmlns="http://host.co.uk/" has been removed) and can be deserialised into the common object type:

<SearchPartsRequest>
  <LocationCode>01</LocationCode>
  <PartCriteria>
    <PartNo>1064762</PartNo>
  </PartCriteria>
  <WildCardSearch>false</WildCardSearch>
</SearchPartsRequest>

De-serialising doesn't seem to matter, you can do this as usual as the namespaces are added back in automatically for you (if you where to serialise again).

OTHER TIPS

You may want to consider customizing your Serialize and Deserialize functions for the namespaces used. As described here: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlattributes.xmlns(v=vs.110).aspx

Xml namespaces. Yours do not match. You need to declare the namespaces correctly, for example:

[XmlElement(Namespace="http://host.co.uk/")]
public string LocationCode {get;set;}

The simplest way to strip out the namespaces is simply to use Regex. Thus (in C# sorry):

var newXml = System.Text.RegularExpressions.Regex.Replace(xml, @"(xmlns:?[^=]=[""][^""][""])", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Multiline);

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top