none
custom serialization - GetObjectData() not being invoked - framework using default serialization RRS feed

  • Question

  • I'm using VS2013 and am trying to experiment with custom serialization in C# code (C# 5, .NET 4.5, Win7 Pro x64).  Here's what I have so far.

    First, a test class which implements custom serialization.  Of course, for this class the custom serialization isn't any benefit but I'm trying to demonstrate the calls are being invoked as expected.

        [Serializable]
        public class Foo : ISerializable
        {
            public string Name { get; set; }
            public int TheAnswer { get; set; }
    
            public Foo()
            {
                Name = "John Doe";
                TheAnswer = 42;
            }
    
            // SERIALIZE (SAVE)
            public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                Trace.WriteLine(">>> custom serialize, SAVE");
                info.AddValue("Name",Name);
                info.AddValue("TheAnswer",TheAnswer);
            }
    
            // DESERIALIZE (LOAD)
            protected Foo(SerializationInfo info, StreamingContext context)
            {
                Trace.WriteLine(">>> custom serialize, LOAD");
                Name = info.GetString("Name");
                TheAnswer = info.GetInt32("TheAnswer");
            }
        }
    

    I then have the below code which is triggered on a button click to demonstrate serializing the above to a file using the binary formatter.

            private const string _testFileName = @"c:\users\dave\testapp.dat";
    
            private void SaveBtn_Click(object sender, RoutedEventArgs e)
            {
                try
                {
                    var foo = new Foo();
    
                    BinaryFormatter binFormat = new BinaryFormatter();
                    using (Stream fStream = File.Create(_testFileName))
                    {
                        binFormat.Serialize(fStream, foo);
                    }
                }
    
                catch (Exception ex)
                {
                    MessageBox.Show("EXCEPTION: " + ex.ToString());
                }
            }
    

    When I run the above code, the serialization doesn't make use of my custom code.  Specifically, GetObjectData() is not called.  I verified this by placing a breakpoint in that code as well as with the Trace line.  Furthermore, I examined the created file and can see its writing out the fields, just using the default binary serialization.

    I'm thinking there's something obvious I'm missing here.  I thought I was following the pattern correctly for custom serialization, but apparently not :)

    Any idea what I'm missing?

    Thursday, September 25, 2014 2:01 PM

Answers


  • When I run the above code, the serialization doesn't make use of my custom code.  Specifically, GetObjectData() is not called.  I verified this by placing a breakpoint in that code as well as with the Trace line.  Furthermore, I examined the created file and can see its writing out the fields, just using the default binary serialization.


    I figured it out.  In order for the custom serialize code to be called, you have to attach a SecurityPermissionAttribute to the code.  So the updated code is as shown below.  This now works and the GetObjectData is invoked.

        [Serializable]
        public class Foo : ISerializable
        {
            public string Name { get; set; }
            public int TheAnswer { get; set; }
    
            public Foo()
            {
                Name = "John Doe";
                TheAnswer = 42;
            }
    
            // SERIALIZE (SAVE)
            [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
            public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                Trace.WriteLine(">>> custom serialize, SAVE");
                info.AddValue("Name",Name);
                info.AddValue("TheAnswer",TheAnswer);
            }
    
            // DESERIALIZE (LOAD)
            [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
            protected Foo(SerializationInfo info, StreamingContext context)
            {
                Trace.WriteLine(">>> custom serialize, LOAD");
                Name = info.GetString("Name");
                TheAnswer = info.GetInt32("TheAnswer");
            }
        }
    

    Thursday, September 25, 2014 2:15 PM

All replies


  • When I run the above code, the serialization doesn't make use of my custom code.  Specifically, GetObjectData() is not called.  I verified this by placing a breakpoint in that code as well as with the Trace line.  Furthermore, I examined the created file and can see its writing out the fields, just using the default binary serialization.


    I figured it out.  In order for the custom serialize code to be called, you have to attach a SecurityPermissionAttribute to the code.  So the updated code is as shown below.  This now works and the GetObjectData is invoked.

        [Serializable]
        public class Foo : ISerializable
        {
            public string Name { get; set; }
            public int TheAnswer { get; set; }
    
            public Foo()
            {
                Name = "John Doe";
                TheAnswer = 42;
            }
    
            // SERIALIZE (SAVE)
            [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
            public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                Trace.WriteLine(">>> custom serialize, SAVE");
                info.AddValue("Name",Name);
                info.AddValue("TheAnswer",TheAnswer);
            }
    
            // DESERIALIZE (LOAD)
            [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
            protected Foo(SerializationInfo info, StreamingContext context)
            {
                Trace.WriteLine(">>> custom serialize, LOAD");
                Name = info.GetString("Name");
                TheAnswer = info.GetInt32("TheAnswer");
            }
        }
    

    Thursday, September 25, 2014 2:15 PM
  • Hello Dave,

    I'm glad to hear that you got it working and thank you for sharing your solutions & experience here. It will be very beneficial for other community members who have similar questions.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, September 26, 2014 1:33 AM
    Moderator