0

I have a BOOKING class that inherits a list (of Message) I was wondering how to serialize this. my BOOKING class contains the property of Message and 3 attributes called partner, transaction and version,

My Message class has numerous properties to create a booking,

now when I want to serialize I use this

Dim z As New BOOKING
Dim x As New Message
z.partner = "company name"
z.transaction = "BOOKING"
z.version = "1.0"
x.MessageType = "C"
x.CustomerNumber = "123"
x.BookingReference = "5845"
x.CustomerBookingReference = "036598"
x.OutwardRoute = "PEMROS"
x.SailingDate = "20120107"
z.Message = x
SaveAsXML(z)

with the save as xmlfunction code below

Public Shared Function SaveAsXML(ByRef val As BOOKING)
    Try

        Dim objStreamWriter As New StreamWriter("c:\ftptest\New Booking\" + val.FileName)
        Dim y As New XmlSerializer(val.GetType)
        y.Serialize(objStreamWriter, val)
        objStreamWriter.Close()

        Return True
    Catch ex As Exception
        Throw ex
    End Try
End Function

any idea where I'm going wrong?

my BOOKING class is as follows

Public Class BOOKING : Inherits List(Of Message)


Private Property MessageProperty As Message

<XmlAttribute>
Public Property partner As String
<XmlAttribute>
Public Property transaction As String
<XmlAttribute>
Public Property version As String


Public Property Message As Message
    Get
        Return MessageProperty
    End Get
    Set(value As Message)
        MessageProperty = value
    End Set
End Property

Also here is the xml created by the above code.

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

Here is my deserializing code

 Try
        Dim Samples As BOOKING
        Using objStreamReader As New StreamReader(filepath) 'Path where file is
            Dim x As New XmlSerializer(GetType(BOOKING), New XmlRootAttribute("BOOKING"))
            Samples = x.Deserialize(objStreamReader)
        End Using
        Form1.DataGridView1.DataSource = Samples
        Return True
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
kpjm0501
  • 21
  • 7
  • What is not working? Do you have an error message? – NePh May 06 '14 at 10:27
  • Hi when I don't have the Booking class inheriting message, It will serialize no problem using the code above, but when it inherits it I get no error and nothing is serialized it still creates the xml file but it's empty – kpjm0501 May 06 '14 at 10:35
  • Possible duplicate of [this](http://stackoverflow.com/questions/1225750/public-fields-properties-of-a-class-derived-from-bindinglistt-wont-serialize) – NePh May 06 '14 at 11:13
  • That duplicate seems to be how to make attributes serialize as well, I'm sorry I'm not too familiar with c#. When I use breakpoints at "z.message = x" and SaveasXML(Z) z.message has all the requirements for the xml but it doesn't seem to pass them to z itself, – kpjm0501 May 06 '14 at 11:48
  • you'll get a proper error message if you change your catch code to `MessageBox.Show(ex.Message)` instead of throwing the same error you are catching. One key to serializing are the attributes used on the classes and properties. Edit your post to show what `Booking` looks like. – Ňɏssa Pøngjǣrdenlarp May 06 '14 at 12:46
  • I've added in the BOOKING class, I'm not throwing ex at the end of the code when I'm serializing I am trying to show an error message but there is none, I've also added the xml that the above code creates. – kpjm0501 May 06 '14 at 13:09
  • a) that Catch makes no sense: you have caught an exception, rather than displaying the message provided, you are Throwing a NEW exception. Since the code is not inside a Try it is an unhandled exception and you may not see anymessage. Use MessageBox. b) a private property as a backing field might be confusing it. Fix the catch to see if there is an error and what it is. As a List(Of T) it should work. – Ňɏssa Pøngjǣrdenlarp May 06 '14 at 13:30
  • Apologies For that, I've added in the proper catch in the code and it still doesn't produce an error, they are both in the proper try end try with catch statements in them, I have made the Private properties public with still no luck, when I put in breakpoints at "z.message = x" I can use the debugger to see z.message has all the information but it doesn't seem to pass them to z. – kpjm0501 May 06 '14 at 14:12
  • yes, I think the serializer just got lost in the tall grass and long weeds when BOOKING included a List of itself. I didnt get an exception either, but that is not how to handle an exception: if you cut your arm, the remedy is not to cut it again. – Ňɏssa Pøngjǣrdenlarp May 06 '14 at 14:56

1 Answers1

0

Your class structure is confusing the serializer. If Booking inherits from List(Of Message) then it makes little sense for it to also have a Message Property Of Type Message (because it is already a message type). It becomes a self reference. There are a few other issues and tweaks I made and it serialized fine:

Public Class BOOKING
    Public Property partner As String
    Public Property transaction As String
    Public Property version As String
    Public Property XMsgs As New List(Of XMessage)
End Class


Public Class XMessage
    Public Property A As String
    Public Property C As String
    Public Property B As String
End Class

a) Public Property Message As Message it is ill advised in VB to give a the property the same name as the type. Hence I used XMessage

b) you where not using XMLAttribute correctly. There should have been several IDE errors and it is not needed for XML serialization

c) To handle more than one Message per packet, I changed XMsgs to a List property. This allows one BOOKING dataset for many messages. If you want 1 Msg Per Booking there is no need for 2 classes and just make it a List(Of Booking).

d) got rid of the private property used as a backing field.

Test and serialization code:

   Dim B As New BOOKING

    B.partner = "abcdef"
    B.transaction = "12345"
    B.version = "1.00.1"
    Dim m As New XMessage

    m.A = "foo"
    m.B = "bar"
    B.XMsgs.Add(m)        ' use List prop as a List

    ' Using block to dispose of streamwriter
    Using sr As New System.IO.StreamWriter("c:\Temp\Booking.xml")
        Dim y As New Serialization.XmlSerializer(B.GetType)
        y.Serialize(sr, B)

    End Using
Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
  • Thank you For this, Just one more question how would you go about deserializing this? here is my code at the moment for deserializing it. I've added in my deserializing code in the original question – kpjm0501 May 06 '14 at 14:46
  • to deserialize: `Dim bb As BOOKING` then `bb = CType(y.Deserialize(New System.IO.StreamReader("c:\Temp\Booking.xml")), BOOKING)` or put it inside a USING block like in the answer – Ňɏssa Pøngjǣrdenlarp May 06 '14 at 14:52
  • I noticed when I run the code that the xml elements are now as follows. All message properties here However as I am passing this to a website it can only be as follows How can I fix this? – kpjm0501 May 06 '14 at 15:05
  • Mine doesnt come out like that for multiple msgs: Booking/Msgs/Message/Message, so we have different implementations. how many msgs are allowed per packet? is there a limit? If the Msgs wrapper is not allowed, you cant use a List – Ňɏssa Pøngjǣrdenlarp May 06 '14 at 15:17
  • I don't have the exact information But I think only one Message is allowed per Booking I'm very new to xml and serializing and I thought the only way to have message inside the booking was as a new class because message held all the properties for the Booking – kpjm0501 May 06 '14 at 15:22
  • you **need** the exact specs to know how to construct this. One Msg per Booking doesnt make sense class-wise or xml-wise since they would be the same thing always. (also doesnt match comment #3 layout) – Ňɏssa Pøngjǣrdenlarp May 06 '14 at 15:28
  • I have a spec and it says to create a booking it has to be as follows, all booking properties – kpjm0501 May 06 '14 at 15:37
  • so the Booking AND Msg properties would go > ? If thats the case, then I think XMLWriter is probably going to work better. XMLSeriaizer is a clever idea, but it wont give the Class-In-Class nesting. BOOKING is like the Root element. – Ňɏssa Pøngjǣrdenlarp May 06 '14 at 17:25