views:

201

answers:

2

Hi,

I'm using OpenAccess disconnected model. When I try to deserialize an object with DataConractSerializer, the Version property of this object is 0 - but only in the xml. If I debug the code and watch the value - it's 1 (or 2,3...)

If I say before the serialization "int temp = object.Version" the seriazlier can save the value.

There is a lazy issue, I'm sure. How can I force to read/save this value without explicit calls?

Code snippets: http://www.telerik.com/community/forums/orm/general-discussions/objectnetworkattacher-vs-datacontractserializer.aspx#775451

+2  A: 

It sounds like the [DataMember] is set against the field (or is defaulting to fields), and is bypassing the lazy behaviour. If you control the type, you could perhaps add an [OnSerializing] method that peeks at this property before serialization kicks in... that way it should have a value, and you won't need to put code into other places.

If the type is generated, look to see if it is a partial class. If so, you can add another partial class of the same name (and same namespace), and put your [OnSerializing] method in there...

Example (uncomment the last block to make it work):

using System;
using System.Runtime.Serialization;
using System.Xml;

class Program {
    static void Main() {
        using (XmlWriter writer = XmlWriter.Create(Console.Out)) {
            new DataContractSerializer(typeof(Foo))
                .WriteObject(writer, new Foo());
        }       
    }
}

[DataContract]
partial class Foo {
    [DataMember(Name="Bar")]
    private int? bar;
    public int Bar {
        get {
            if (bar == null) bar = 27; // somthing lazy
            return bar.GetValueOrDefault();
        }
        set { bar = value; }
    }
}
/* UNCOMMENT THIS
partial class Foo {
    [OnSerializing]
    private void BeforeSerialize(StreamingContext ctx) {
        int tmp = Bar;
    }
}
*/
Marc Gravell
Great workaround! With one base class for all my DAL classes can solve the problem. If Telerik says nothing about that issue, I think your answer is a great solution.
boj
If it is a base-class, you might want to make "BeforeSerialize" protected virtual, so that inherited classes can add to the party...
Marc Gravell
Yes...but sadly OpenAcces works not easy with base classes (or I'm just missing something, this is my first day as OA user). It ignores inherited members in the child class's "Persistent" attribute - but this is maybe a new thread:)
boj
+2  A: 

Hi, you should call the .Retrieve() method on your object which will load all the lazy-loaded fields and you will have all the data required for serialization. Hope that helps.

That's the answer, thank you.
boj