As the title says, i am having some problems with serializing my auto generated POCO objects. But first some background information:
I have created my Data Access Layer using EF 4.0 en ADO.Net POCO Entity Generator following this guide: http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx .
I have now 2 class libraries, one with EF model and second with T4 Auto generated POCO entities.
Currently i am working on another project where i want to use my DAL class libraries. I must retrieve some objects and serialize them to XML. First i tried XmlSerializer, but then i found out that it has problems with circural references. I fixed this problem using XmlIgnore, but then i had problem with serializing:
Public Overridable Property NwlGroup As ICollection(Of NwlGroup)
Because XmlSerializer does not support interfaces.
Second i tried DataContractSerializer with [DataContract] and [DataMember] attributes in autogenerated entity Poco Class file. This worked, but naturally i had to clean up the changes from the auto generated file, therefor i wanted to use MetaDataType attribute. I created extra file like this:
Imports System.Runtime.Serialization
Imports System.ComponentModel.DataAnnotations
<MetadataType(GetType(NewsletterCustomerMetadata))>
Partial Public Class NewsletterCustomer
End Class
<DataContract()
Public Class NewsletterCustomerMetadata
<DataMember(Name:="emailaddress", IsRequired:=True)>
Public Overridable Property Emailaddress As String
<DataMember(Name:="name")>
Public Overridable Property Name As String
<DataMember()>
Public Overridable Property NwlGroup As ICollection(Of NwlGroup)
End Class
Auto generated file:
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated from a template.
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.Runtime.Serialization
Public Class NewsletterCustomer
#Region "Primitive Properties"
Public Overridable Property ID As Integer
Public Overridable Property Emailaddress As String
Public Overridable Property Name As String
...
#Region "Navigation Properties"
Public Overridable Property NwlGroup As ICollection(Of NwlGroup)
Get
If _nwlGroup Is Nothing Then
Dim newCollection As New FixupCollection(Of NwlGroup)
AddHandler newCollection.CollectionChanged, AddressOf FixupNwlGroup
_nwlGroup = newCollection
End If
Return _nwlGroup
End Get
Set(ByVal value As ICollection(Of NwlGroup))
If _nwlGroup IsNot value Then
Dim previousValue As FixupCollection(Of NwlGroup) = TryCast(_nwlGroup, FixupCollection(Of NwlGroup))
If previousValue IsNot Nothing Then
RemoveHandler previousValue.CollectionChanged, AddressOf FixupNwlGroup
End If
_nwlGroup = value
Dim newValue As FixupCollection(Of NwlGroup) = TryCast(value, FixupCollection(Of NwlGroup))
If newValue IsNot Nothing Then
AddHandler newValue.CollectionChanged, AddressOf FixupNwlGroup
End If
End If
End Set
End Property
Private _nwlGroup As ICollection(Of NwlGroup)
...
End Class
Then i try to serialize it to xml
Dim ctx = New ModelEntities(_connectionString)
ctx.ContextOptions.ProxyCreationEnabled = False
ctx.ContextOptions.LazyLoadingEnabled = False
Dim customers = From c In ctx.NwlCustomer
Select c
Where c.SiID = 99
Dim filename As String = "C:\test.txt"
Dim result As NewsletterCustomer = customers.ToList.FirstOrDefault
Dim writer As New FileStream(filename, FileMode.Create)
Dim ser As New DataContractSerializer(GetType(NewsletterCustomer))
ser.WriteObject(writer, customers.ToList.FirstOrDefault)
writer.Close()
This gave me NewsletterCustomer xml with all read / write properties serialized as you would excpect when no DataContract is specified. If i move DataContract attribute from NewsletterCustomerMetadata to NewsletterCustomer then i only get the root node as you would expect when DataContract is specified with no DataMember attributes.
It looks like DataContractSerializer don't work with MetaDataType Data Annotations.
My Questions are:
- How can i serialize my POCO Classes to CUSTOM XML?
- How can i add [DataContract] and [DataMember] attributes to auto generated POCO classes?
- What is the best way to serialize Auto Generated POCO classes to XML?