Solved

XML Serialization - remove version node

Posted on 2013-06-12
4
597 Views
Last Modified: 2013-06-13
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
Comment
Question by:LandyJ
  • 2
4 Comments
 
LVL 35

Accepted Solution

by:
mccarl earned 500 total points
ID: 39243691
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
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 39244440
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
 
LVL 7

Author Closing Comment

by:LandyJ
ID: 39245362
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
 
LVL 35

Expert Comment

by:mccarl
ID: 39246476
Glad you were able to get it working! ;)
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

For some reason Google Apps has decided to reserve 'www' for your new domain which results in an error when trying to map the web address 'www' to a certain site in your Google Sites. The error is 'this address is already being used' and after some …
The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
The purpose of this video is to demonstrate how to set up the WordPress backend so that each page automatically generates a Mailchimp signup form in the sidebar. This will be demonstrated using a Windows 8 PC. Tools Used are Photoshop, Awesome…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now