How can I implement ISerializable in .NET 4+ without violating inheritance security rules?

前端 未结 3 1104
没有蜡笔的小新
没有蜡笔的小新 2021-01-30 19:29

Background: Noda Time contains many serializable structs. While I dislike binary serialization, we received many requests to support it, back in the 1.x timeline. We support it

3条回答
  •  借酒劲吻你
    2021-01-30 19:48

    According to the MSDN see:

    How to Fix Violations?

    To fix a violation of this rule, make the GetObjectData method visible and overridable and make sure all instance fields are included in the serialization process or explicitly marked with the NonSerializedAttribute attribute.

    The following example fixes the two previous violations by providing an overrideable implementation of ISerializable.GetObjectData on the Book class and by providing an implementation of ISerializable.GetObjectData on the Library class.

    using System;
    using System.Security.Permissions;
    using System.Runtime.Serialization;
    
    namespace Samples2
    {
        [Serializable]
        public class Book : ISerializable
        {
            private readonly string _Title;
    
            public Book(string title)
            {
                if (title == null)
                    throw new ArgumentNullException("title");
    
                _Title = title;
            }
    
            protected Book(SerializationInfo info, StreamingContext context)
            {
                if (info == null)
                    throw new ArgumentNullException("info");
    
                _Title = info.GetString("Title");
            }
    
            public string Title
            {
                get { return _Title; }
            }
    
            [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
            protected virtual void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                info.AddValue("Title", _Title);
            }
    
            [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
            void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
            {
                if (info == null)
                    throw new ArgumentNullException("info");
    
                GetObjectData(info, context);
            }
        }
    
        [Serializable]
        public class LibraryBook : Book
        {
            private readonly DateTime _CheckedOut;
    
            public LibraryBook(string title, DateTime checkedOut)
                : base(title)
            {
                _CheckedOut = checkedOut;
            }
    
            protected LibraryBook(SerializationInfo info, StreamingContext context)
                : base(info, context)
            {
                _CheckedOut = info.GetDateTime("CheckedOut");
            }
    
            public DateTime CheckedOut
            {
                get { return _CheckedOut; }
            }
    
            [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
            protected override void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                base.GetObjectData(info, context);
    
                info.AddValue("CheckedOut", _CheckedOut);
            }
        }
    }
    

提交回复
热议问题