代码之家  ›  专栏  ›  技术社区  ›  David

将用[datacontract]修饰的对象放入stateserver?

  •  3
  • David  · 技术社区  · 15 年前

    有没有什么东西可以粘上 DataContract 属性,但未用修饰 Serializable sqlserver stateserver中的属性?换句话说,我不希望用 可串行化的 我还必须在所有这些对象上实现IXmlSerizable属性,因为它们没有空的contstructor和属性的非公共setter。

    2 回复  |  直到 12 年前
        1
  •  2
  •   marc_s    15 年前

    很不幸,没有绝对简单的方法可以做到这一点。

    但是:asp.net会话状态机制是可扩展的,因此您可以设想编写自己的asp.net会话状态提供程序,该程序基本上使用datacontractSerializer,并将序列化对象存储到SQL Server(或任何其他存储区)中。

    退房 MSDN Session-State Modes Implementing a Session-State Store Provider .

    切换到flick并不是一个简单的小问题,但它绝对是可行的。

    或者只是用 [Serializable] 别再这样了…

        2
  •  1
  •   Community CDub    8 年前

    我认为您需要的是实现ISerializable并使用DataContractSerializer手动序列化。

    请看下面的答案:

    Using WCF DataContract in MVC SessionState using AppFabric cache

    在讨论使用appfabric(stateserver)时,同样的问题也适用于sqlsessionstatestore(所有oob状态提供程序都对复杂的对象图使用binaryformatter)

    我只是在一个项目上做了这个,效果很好。(这很简单)

    然而,在我的例子中,我不想只序列化标记为[datacontract]的项,因为我的[datacontract]类嵌套在整个层次结构中,我不想在每个级别包装所有这些实体。(datacontract项是服务引用dto,用作状态对象的备份数据)。相反,我只是简单地包装了根元素,它是我在会话中填充的项的一个成员。

    我承认这有点难理解,所以我包含了下面的代码:

    /// <summary>
    /// Represents a thread-safe, per-session state object, stored in the ASP.NET Session. 
    /// </summary>
    [Serializable]
    public class SessionContext 
    {
        #region Static
        private const string SESSION_CONTEXT_KEY = "SessionContext";
        private static object _syncRoot = new object();
    
        public static SessionContext Current
        {
            get
            {
                HttpSessionState session = HttpContext.Current.Session;
    
                if (session[SESSION_CONTEXT_KEY] == null)
                {
                    lock (_syncRoot)
                    {
                        if (session[SESSION_CONTEXT_KEY] == null)
                        {
                            session[SESSION_CONTEXT_KEY] = new SessionContext();
                        }
                    }
                }
    
                return (SessionContext)session[SESSION_CONTEXT_KEY];
            }
        }
        #endregion
    
        private SessionContext()
        {
        }
    
        public User User { get; set; }
    
        private CustomerWrapper _customerWrapper = new CustomerWrapper();
        /// <summary>
        /// ignore serializing the Customer object because we're serializing the wrapper object instead, which uses the more robust DataContractSerializer.
        /// </summary>
        [XmlIgnore]
        public Customer Customer
        {
            get
            {
                return this._customerWrapper.Customer;
            }
            set
            {
                this._customerWrapper.Customer = value;
            }
        }
    
    }
    
    /// <summary>
    /// Custom wrapper object to instruct the OutOfProc StateProvider how to serialize this item. 
    /// Instead of using the BinaryFormatter, we'll use the more robust DataContractSerializer.
    /// </summary>
    [Serializable]
    public class CustomerWrapper : ISerializable
    {
        public Customer Customer { get; set; }
    
        internal CustomerWrapper() { }
        internal CustomerWrapper(Customer customer) : this() { this.Customer = customer; }
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (this.Customer != null)
            {
                info.AddValue("IsNull", false);
    
                using (var ms = new MemoryStream())
                {
                    try
                    {
                        var serializer = new DataContractSerializer(this.Customer.GetType());
                        serializer.WriteObject(ms, this.Customer);
                        info.AddValue("Bytes", ms.ToArray());
                        info.AddValue("IsDataContract", true);
                    }
                    catch (Exception ex) 
                    { // breakpoint never hit
    
                    }
                }
    
                info.AddValue("Type", this.Customer.GetType());
            }
            else
            {
                info.AddValue("IsNull", true);
            }
        }
        public CustomerWrapper(SerializationInfo info, StreamingContext context)
        {
            if (!info.GetBoolean("IsNull"))
            {
                var type = info.GetValue("Type", typeof(Type)) as Type;
    
                using (var ms = new MemoryStream(info.GetValue("Bytes", typeof(byte[])) as byte[]))
                {
                    var serializer = new DataContractSerializer(type);
                    this.Customer = (Customer)serializer.ReadObject(ms);
                }
            }
        }
    }