Automatically generated POCO serialization with task DataContractSerializer and MetaDataTypeAttribute

As the name says, I am having some problems serializing my automatically created POCO objects. But first, some information:

I created my data access level using EF 4.0 en ADO.Net POCO Entity Generator by following this guide: http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template -for-the-entity-framework.aspx .

I now have 2 class libraries, one with an EF model and the second with T4 Auto generated POCO objects.

I am currently working on another project where I want to use DAL class libraries. I have to get some objects and serialize them in XML. At first I tried XmlSerializer, but then I found out that it has problems with circulation links. I fixed this problem with XmlIgnore, but then I had a serialization problem:

Public Overridable Property NwlGroup As ICollection(Of NwlGroup) 

Because XmlSerializer does not support interfaces.

Second, I tried a DataContractSerializer with the [DataContract] and [DataMember] attributes in a Poco Class file with an auto-generated entity. This worked, but naturally, I had to clear the changes from the automatically generated file, so I wanted to use the MetaDataType attribute. I created an additional file as follows:

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 in 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()

NewsletterCustomer xml /, , , DataContract. DataContract NewsletterCustomerMetadata NewsletterCustomer, root node, , DataContract DataMember.

, DataContractSerializer MetaDataType.

:

  • POCO CUSTOM XML?
  • [DataContract] [DataMember] POCO?
  • Auto Generated POCO XML?
+3
3

DataContractSerializer . .NET API, , .

IXmlSerializable DTO @Marc. DataContractSerializer IDataContractSurrogate. XmlSerializer XML.

, T4 , , :

  • EDMX ( XML) CSDL (, ). XML. ( SQL).
  • T4, .
+1

XmlSerializer, , .

, : xml - - . DataContractSerializer xml, : XmlSerializer , ( [XmlIgnore] ).

: IXmlSerializable, , , .

+2

, , XML-. , , XML, , XML.

Code First POCO EDMX. T4 , ToXmlElement FromXmlElement.

:

  • .
  • .

. . , , , , ( ). , FixUpCollection, EF POCO.

public System.Xml.XmlElement ToXmlElement (System.Xml.XmlDocument document)
{
    return (this.ToXmlElement(document, 3, new System.Collections.Generic.List<object>()));
}

public System.Xml.XmlElement ToXmlElement (System.Xml.XmlDocument document, int level)
{
    return (this.ToXmlElement(document, level, new System.Collections.Generic.List<object>()));
}

public System.Xml.XmlElement ToXmlElement (System.Xml.XmlDocument document, int level, System.Collections.Generic.List<object> collection)
{
    System.Xml.XmlElement element = null;

    collection.Add(this);

    element = document.CreateElement(System.Data.Objects.ObjectContext.GetObjectType(this.GetType()).Name);

    // Native Types.
    element.Attributes.Append(document, "Id", this.Id.ToString());
    element.Attributes.Append(document, "Assessment_StudentId", this.Assessment_StudentId.ToString());

    // Complex Types.

    // Foreign Keys.
    if (!collection.Contains(this.Assessment_Student) && level > 0) { element.AppendChild(this.Assessment_Student.ToXmlElement(document, level - 1, collection)); }
    if (!collection.Contains(this.PackageServer) && level > 0) { element.AppendChild(this.PackageServer.ToXmlElement(document, level - 1, collection)); }
    if (!collection.Contains(this.PackageClient) && level > 0) { element.AppendChild(this.PackageClient.ToXmlElement(document, level - 1, collection)); }

    // Child Objects.
    foreach (Core.SessionTasks _SessionTasks in this.SessionTasks)
    {
        if (!collection.Contains(_SessionTasks) && level > 0)
        {
            collection.Add(_SessionTasks);
            element.AppendChild(_SessionTasks.ToXmlElement(document, level - 1, collection));
        }
    }

    return (element);
}

public bool FromXmlElement (System.Xml.XmlElement element)
{
    bool result = true;

    //this.InitializeData();

    // Native Types.
    this.Id = int.Parse(element.Attributes ["Id"].Value);
    this.Assessment_StudentId = int.Parse(element.Attributes ["Assessment_StudentId"].Value);

    // Complex Types.

    // Foreign Keys.
    Core.Assessment_Student __Assessment_Student = new Core.Assessment_Student();
    if (element ["Assessment_Student"] != null)
    {
        __Assessment_Student.FromXmlElement(element ["Assessment_Student"]);
        this.Assessment_Student = __Assessment_Student;
    }

    Core.PackageServer __PackageServer = new Core.PackageServer();
    if (element ["PackageServer"] != null)
    {
        __PackageServer.FromXmlElement(element ["PackageServer"]);
        this.PackageServer = __PackageServer;
    }

    Core.PackageClient __PackageClient = new Core.PackageClient();
    if (element ["PackageClient"] != null)
    {
        __PackageClient.FromXmlElement(element ["PackageClient"]);
        this.PackageClient = __PackageClient;
    }

    // Child Objects.
    this.SessionTasks.FromXmlElement(element ["SessionTasks"]);

    return (result);
}
+1

All Articles