将用[DataContract]修饰的对象放入StateServer?

发布于 2024-08-25 03:48:34 字数 194 浏览 12 评论 0原文

无论如何,是否可以将使用 DataContract 属性装饰但未使用 Serialized 属性装饰的对象粘贴到 SqlServer StateServer 中?换句话说,我宁愿不必使用 Serialized 属性来装饰这些对象,因为我还必须在所有这些对象上实现 IXmlSerizable,因为它们没有空的构造函数和非公共 setter对于属性。

Is there anyway to stick objects which are decorated with DataContract attributes but not decorated with Serializable attributes in to a SqlServer StateServer? In other words, I would prefer not having to decorate these objects with the Serializable attribute as I will also have to implement IXmlSerizable on all of these objects because they do not have empty contstructors, and non-public setters for properties.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光病人 2024-09-01 03:48:34

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

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

查看 MSDN 会话状态模式实现会话状态存储提供程序

这不是一个简单的轻弹开关——但它绝对是可行的。

或者只是用 [Serialized] 装饰你的对象并完成它......

There's no absolutely easy-peasy way to do this, no, unfortunately.

But: the ASP.NET session state mechanism is extensible, so you could imagine writing your own ASP.NET session state provider which basically uses the DataContractSerializer, and stores the serialized objects into SQL Server (or any other store, for that matter).

Check out MSDN Session-State Modes and Implementing a Session-State Store Provider.

Not a simple little switch to flick - but it would definitely be doable.

Or just decorate your objects with [Serializable] and be done with it...

榕城若虚 2024-09-01 03:48:34

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

看看这里的答案:

在 MVC SessionState 中使用 WCF DataContract使用AppFabric缓存

虽然这是在谈论使用AppFabric(StateServer),但同样的问题也适用于SqlSessionStateStore(所有OOB StateProviders都使用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);
            }
        }
    }
}

I think what you want is to implement ISerializable and manually serialize with the DataContractSerializer.

Have a look at the answer here:

Using WCF DataContract in MVC SessionState using AppFabric cache

While this is talking about using AppFabric (StateServer), the same problem applies to SqlSessionStateStore (all the OOB StateProviders use BinaryFormatter for complex object graphs)

I just had to do this on a project and it worked great. (and it was easy-peasy)

In my case, however, I didn't want to only serialize items marked with [DataContract] because my [DataContract] classes were nested throughout the hierarchy, and I did not want to wrap all of those entities at every level. (the DataContract items are Service Reference DTOs used as backing data for state objects). Instead I simply wrapped the root element that was a member of the item I was stuffing into the Session.

I'll admit that's kinda hard to follow, so I've included the code below:

/// <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);
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文