• Visitors can check out the Forum FAQ by clicking this link. You have to register before you can post: click the REGISTER link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below. View our Forum Privacy Policy.

.NET 2.0 Detecting deserialization

Collapse
X
  •  
  • Filter
  • Time
  • Show
Clear All
new posts

    #11
    Originally posted by TheRefactornator View Post
    That's exactly what I proposed.
    .
    Indeed, I was just trying to put it to him/her again.

    Comment


      #12
      Originally posted by TheRefactornator View Post
      Can you reverse the logic? i.e. The prop setters are disabled by default and only enabled in the serialization constructor? It seems like this will work because if an empty class instance is created locally then all prop setters are auto-disabled for that instance, and they are only enabled when serialization is underway. It seems a simple solution but perhaps I'm missing something.
      Unfortunately not. Using default serialization requires a parameterless public constructor. Naturally I could add another private constructor, but the issue is I still cannot tell if the object is going to be deserialized or not.

      The calls are:-

      New, optional OnDeserialised, any other calls into the object. Whether or not the object is being deserialised (which is the only place the setting will be valid) is always indeterminate.

      Of course I could easily enough add logic into the other methods to detect the properties were set and the object was not deserialised (thus the sets are invalid) but this cannot happen until the client next does something with the object. Equally I could add a method for the client to call after construction to denote whether it was deserilized or not. But I want to be able to tell the client it's been naughty at the point it is.

      The workaround is to save the data locally in some local variables and populate the actual variables underlying the properties at the point OnDeserialized is called (as implied by yourself and DP). This gives a workaround but means I can't throw an IllegalOperation exception at the time a client populates said properties when it shouldn't.

      Hence I do really want to know "being deserialized", followed by "been deserialized".

      It does look as though the only viable choice in to add the OnDeserializing and OnDeserialized attributes to an apporpritate method to control it.

      Comment


        #13
        Sorry I don't get it. Below is some sample code to show the method I'm thinking of and it demonstrates that the serialization constructor is called ONLY when the class is being instantiated by the deserialization process. Client classes attempting to instantiate this class directly cannot use the serialization constructor because it has the protected access modifier.

        So as mentioned earlier you can set your flag in the serialization constructor to enable the prop setters if you need to, but clients directly instantiating the class can never do this and this means if the flag is not set and a client attempts to call one of the prop setters you are able to throw your exception. Then if you also implement IDeserializationCallback.OnDeserialization you can switch the flag off at the end of the deserialization process if you need to.

        Perhaps you're attempting to avoid doing something like this..or it's just too ugly..but I can't see why it doesn't work.


        using System;
        using System.Runtime.Serialization;
        namespace ClassLibrary
        {
        [Serializable]
        publicclassSerializableClass: ISerializable
        {
        ///<summary>
        /// Initializes a new instance of the <see cref="SerializableClass"/> class.
        ///</summary>
        public SerializableClass ()
        {
        //Regular constructor for client classes
        }
        ///<summary>
        /// Initializes a new instance of the <see cref="SerializableClass"/> class.
        ///</summary>
        ///<param name="info">The info.</param>
        ///<param name="context">The context.</param>
        protected SerializableClass(
        SerializationInfo info,
        StreamingContext context)
        {
        //Serialization constructor
        //note this is a protected constructor therefore is only callable by the serialization process
        //and not by client classes attempting to instantiate this thing directly
        }

        #region ISerializable Members
        publicvoid GetObjectData(SerializationInfo info, StreamingContext context)
        {
        //do your custom stuff in here if you need to..
        }
        #endregion
        }
        publicclassClientClass
        {
        public ClientClass()
        {
        SerializableClass aclass = newSerializableClass();
        }
        }
        }
        Moving to Montana soon, gonna be a dental floss tycoon

        Comment


          #14
          Yes, that fine. But sadly is not the situation I am in.

          The class does not implement ISerializable and I am trying to avoid having to do so because it a base class which is inherited all over the place. ISerializable would need to be implemented in all the derived classes - and I am not in control of these. [aiui the serializer won't call the base implementation of the method - but I need to check this further; I couldn't get it to work yesterday]

          The properties in question are a few properties in the base class.

          Comment


            #15
            That makes more sense now - rock and hard place. When instantiating a descendant class, the base class methods / contructors need to be called directly by the descendant..since you're not in control of these that makes this even more difficult to solve.

            Oh the joys of OO. Good luck.
            Moving to Montana soon, gonna be a dental floss tycoon

            Comment

            Working...
            X