views:

181

answers:

2

Using the following code:

    Private Sub MakeMeSomeXmlBeforeRyanGetsAngry()

    Dim db As New MyDBDataContext

    Dim customer = From c In db.Customers Select c

    Dim dcs As New DataContractSerializer(GetType(Customer))

    Dim sb As StringBuilder = New StringBuilder
    Dim writer As XmlWriter = XmlWriter.Create(sb)
    dcs.WriteObject(writer, customer)
    Dim xml As String = sb.ToString

    Response.Write(xml)

End Sub

I am attempting to serialize my linq collection of customers. But it keeps throwing

Type 'System.Data.Linq.DataQuery`1[MyDB.Customer]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.

My issue is that I have already marked the dbml Serialization Mode to UniDirectional and when I check the dbml codebehind all of the DataContract()> and DataMember()> elements are there.

I am not sure how to proceed. I have tried adding various dataloadoptions and setting deferredloading to false, but no luck.

Ideas?

+2  A: 

I think the problem arises because LINQ queries are processed only on demand, and are not serializable. Try to serialize a serializable data type resulting from your LINQ query (array, list, a single item, etc.)

dcs.WriteObject(writer, customer.ToArray)

(I assume you only need to serialize the results of the query, and not the query itself)

M.A. Hanin
I tried what you suggested and now I am getting the following error message. Type 'MyDB.Customer[]' with data contract name 'ArrayOfCustomer:http://schemas.datacontract.org/2004/07/MyDB' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer. Any other ideas?
bulltorious
Can you show the relevant code of your contract?
M.A. Hanin
Where would I find that? .dbml?
bulltorious
+1  A: 

This is working for me with Serialization Mode property of .dbml set to UniDirectional:

Public Shared Function CreateXml(Of T)(ByVal item As T) As String
    Dim result As String = ""
    Dim memoryStream As New IO.MemoryStream()
    Dim serializer As New DataContractSerializer(GetType(T))
    serializer.WriteObject(memoryStream, item)
    memoryStream.Position = 0
    Using reader As New StreamReader(memoryStream)
        result = reader.ReadToEnd()
    End Using
    memoryStream.Close()
    Return result
End Function

Dim db As New SerializerDataContext()
Dim questions = db.Questions.ToList()

Dim xmlFileName As String = "D:\\xml_test.xml"
If My.Computer.FileSystem.FileExists(xmlFileName) Then My.Computer.FileSystem.DeleteFile(xmlFileName)

Dim xml As String = XmlHelper.CreateXml(Of List(Of Question))(questions)
My.Computer.FileSystem.WriteAllText(xmlFileName, xml, True)
RJBrady
That worked well for me. Thanks!
bulltorious