• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 638
  • Last Modified:

XML Serialization - remove version node

Hopefully I will include enough info, if not, let me know. I’ll provide whatever I can.

I have a class…

      <DataContract(name:="VendorTowStatus", namespace:="http://ws.myweb.com/Vendors/vend")> _
      Public Class VendorTowStatus
            Private _tokenid As String = ""
            <DataMember(name:="TokenID")> _
            Public Property TokenID() As String
                  Get
                        Return _tokenid
                  End Get
                  Set(ByVal value As String)
                        _tokenid = value
                  End Set
            End Property

            Private _orderid As String = ""
            <DataMember(name:="OrderID")> _
            Public Property OrderID() As String
                  Get
                        Return _orderid
                  End Get
                  Set(ByVal value As String)
                        _orderid = value
                  End Set
            End Property

            Private _status As String
            <DataMember(name:="Status")> _
            Public Property Status() As String
                  Get
                        Return _status
                  End Get
                  Set(ByVal value As String)
                        _status = value
                  End Set
            End Property
      End Class
      
…that I am trying to serialize to POST to a web service using this code:

      Dim status As New VendorTowStatus
      With status
            .TokenID = "123456"
            .OrderID = "123456789"
            .Status = "Success"
      End With

      Dim xml As New Xml.Serialization.XmlSerializer(status.GetType)
      Dim data() As Byte, xmlstr As New MemoryStream
      xml.Serialize(xmlstr, status)
      xmlstr.Position = 0
      data = New Byte(CType(xmlstr.Length, Integer)) {}
      xmlstr.Read(data, 0, xmlstr.Length)

      Debug.Print(System.Text.ASCIIEncoding.ASCII.GetString(data, 0, data.Length - 1))

This produces via Debug.Print(System.Text.ASCIIEncoding.ASCII.GetString(data, 0, data.Length - 1)):
      <?xml version="1.0"?>
      <VendorTowStatus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <TokenID>123456</TokenID>
        <OrderID>123456789</OrderID>
        <Status>Success</Status>
      </VendorTowStatus>

But it needs to produce:
      <VendorTowStatus xmlns="http://ws.myweb.com/Vendors/vend">
        <TokenID>123456</TokenID>
        <OrderID>123456789</OrderID>
        <Status>Success</Status>
      </VendorTowStatus>
(Remove the “<?xml declaration and include the ns setting)

Obviously, I’m missing a step (or 5). I have the WebRequest GetRequestStream/GetResponseStream code working. When I send the results of the Serialization above, I get a "(400) Bad Request." response. If I hardcode the XML string instead of serializing the VendorTowStatus object, I get the expected response.

If anyone can show what I’m missing, I’d appreciate it.  Thanks.
0
LandyJ
Asked:
LandyJ
  • 2
1 Solution
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
It appears that you are mixing up 2 different types of functionality, XmlSerializer and DataContractSerializer. Check out these links for a bit more info...

http://stackoverflow.com/questions/2505778/datacontractserializer-vs-xmlserializer-pros-and-cons-of-each-serializer
http://dotnet-journey.blogspot.com.au/2010/11/difference-between-xmlserializer-and.html


Firstly, to removing the "xml declaration", I'm not sure that either of the above methods have anyway to reomve that. However, I would doubt that the webservice is having issues with this, it is probably just the missing namespace that is the issue. If this isn't the case, then as well as protesting to the web service provider about a buggy service, you could probably just serialize your object as normal and then use String methods to remove that declaration. Yes, its a hack but that is the price when communicating to a really non-standard web service.


On to the namespace issue, basically it is because you are using the attributes pertaining to a DataContractSerializer in the class, but using the XmlSerialzer to do the work. So you have 3 options...

- Quick and easy, create your XmlSerialzer like so  Dim xml As New Xml.Serialization.XmlSerializer(status.GetType, "http://ws.myweb.com/Vendors/vend")   This sets the default namespace fro the serialized xml and so should just work. You could also then remove all the <DataContract, <DataMember attributes in your class since they aren't doing anything.

- Change the <DataContract, <DataMember attributes to <XmlRootAttribute, <XmlElement attributes so that the XmlSerialzer picks up the values and serializes correctly.

- Change to using the DataContractSerializer instead and then you keep the <DataContract, <DataMember attributes as they are.
0
 
käµfm³d 👽Commented:
I'm not sure that either of the above methods have anyway to reomve that.
If you create your own XmlWriter and pass it to the XmlSerializer, you can remove the version node (via an XmlWriterSettings object passed to the writer).

e.g.

Imports System.Xml
Imports System.Xml.Serialization
Imports System.IO

Module Module1

    Sub Main()
        Dim settings As New XmlWriterSettings() With {.OmitXmlDeclaration = True}
        Dim ms As New MemoryStream()
        Dim writer As XmlWriter = XmlWriter.Create(ms, settings)
        Dim serializer As New XmlSerializer(GetType(String))

        serializer.Serialize(writer, "serialize me")

        ms.Position = 0

        Dim xml As String = Encoding.UTF8.GetString(ms.ToArray())
    End Sub

End Module

Open in new window

0
 
LandyJAuthor Commented:
Thank you very much. I was able to clean up the class and get the XML formatted correctly (it was unnecessary to remove the declaration). I'm having other issues, but I think they're related to something else I found.with the ws I'm trying to consume (like the order of the nodes is specific - OrderID has to be first, that's why I thought the declaration had to be removed. I didn't notice that TokenId  was first in one example and OrderID was first in the other).

But for the answer to this question:
The class is now:
<Serialization.XmlRoot(elementname:="VendorTowStatus", namespace:="http://mobilesolutions.thedigitalgroup.com/TipsyTowVendorService/Enrollment")> _
Public Class VendorTowStatus
      Private _orderid As String = ""
      <Serialization.XmlElement(elementname:="OrderID")> _
      Public Property OrderID() As String
            Get
                  Return _orderid
            End Get
            Set(ByVal value As String)
                  _orderid = value
            End Set
      End Property

      Private _tokenid As String = ""
      <Serialization.XmlElement(elementname:="TokenID")> _
      Public Property TokenID() As String
            Get
                  Return _tokenid
            End Get
            Set(ByVal value As String)
                  _tokenid = value
            End Set
      End Property

      Private _status As String
      <Serialization.XmlElement(elementname:="Status")> _
      Public Property Status() As String
            Get
                  Return _status
            End Get
            Set(ByVal value As String)
                  _status = value
            End Set
      End Property
End Class

and the XML being created and sent that is working just fine is:
<?xml version="1.0"?>
<VendorTowStatus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ws.myweb.com/Vendors/vend">
  <OrderID>12345679</OrderID>
  <TokenID>123456</TokenID>
  <Status>Success</Status>
</VendorTowStatus>
0
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
Glad you were able to get it working! ;)
0

Featured Post

When ransomware hits your clients, what do you do?

MSPs: Endpoint security isn’t enough to prevent ransomware.
As the impact and severity of crypto ransomware attacks has grown, Webroot has fought back, not just by building a next-gen endpoint solution capable of preventing ransomware attacks but also by being a thought leader.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now