【问题标题】:Session state serialization会话状态序列化
【发布时间】:2009-04-13 09:29:51
【问题描述】:

我的会话对象序列化有问题。我做错了什么?我尝试使用 XmlSerializer 和 BinaryFormatter 序列化该对象,没有问题。

当我尝试将购物篮对象保存到会话时,我会得到错误:

无法序列化会话状态。在“StateServer”和“SQLServer”模式下,ASP.NET 将序列化会话状态对象,因此不允许不可序列化的对象或 MarshalByRef 对象。如果自定义会话状态存储在“自定义”模式下完成类似的序列化,则同样的限制也适用。

这是对象:

[Serializable]
public class Basket
{
    #region Fields (2)

    [NonSerialized]
    private CMS.CmsEntity db;

    private List<ShopOrderItem> ShopOrderItems;

    #endregion Fields

    #region Properties (2)

    public bool IsEmpty
    {
        get
        {
            return (this.Items.Count == 0);
        }
    }

    public List<ShopOrderItem> Items
    {
        get
        {
            if (this.ShopOrderItems == null)
            {
                this.ShopOrderItems = new List<ShopOrderItem>();
            }

            return this.ShopOrderItems;
        }
        set
        {
            this.ShopOrderItems = value;
        }
    }

    #endregion Properties

    #region Delegates and Events (1)

    // Events (1) 

    public event EventHandler CartItemsChanged;

    #endregion Delegates and Events

    #region Methods (9)


    public int CountItems()
    {
        return this.ShopOrderItems.Sum(s => s.Quantity);
    }
    public decimal CountTotalAmount()
    {
        ...
    }
    public decimal CountTotalAmountWithoutVAT()
    {
        ...
    }
    public CMS.ProductVariant GetProductVariantById(int id)
    {
        ...
    }


    #region AddProductToCart
    public void AddProductToCart(int productVariantId, int quantity)
    {
        AddProductToCart(GetProductVariantById(productVariantId), quantity);
    }
    public void AddProductToCart(ProductVariant productVariant, int quantity)
    {
        ...
    }
    #endregion

    #region RemoveProductFromCart
    public void RemoveProductFromCart(int productVariantId)
    {
        RemoveProductFromCart(GetProductVariantById(productVariantId));
    }
    public void RemoveProductFromCart(ProductVariant productVariant)
    {
        ..
    }
    #endregion

    #region UpdateProductQuantity
    public void UpdateProductQuantity(int variantId, int quantity, bool isRelative)
    {
        UpdateProductQuantity(GetProductVariantById(variantId), quantity, isRelative);
    }
    public void UpdateProductQuantity(ProductVariant productVariant, int quantity, bool isRelative)
    {
        ...
    }
    #endregion

    #endregion Methods}

使用会话操作的代码:

public static class CurrentSession
{                  

#region public static Basket Basket
public static Basket Basket
    {
        get
        {
                        Basket c = SessionHelper.GetSessionObject("UserCart") as Basket;

                        if (c == null)
                        {
                            c = new Basket();
                            SessionHelper.SetSessionObject("UserCart", c);  // If i comment this line, exception is not thrown
                        }

                        return c;
        }
        set
        {
                        SessionHelper.SetSessionObject("UserCart", value);
        }
    }
    #endregion

}

如果我使用 InProc 会话状态,它可以工作。所以一定是在序列化过程中

【问题讨论】:

    标签: c# session serialization


    【解决方案1】:

    由于我们没有您的其余代码,因此我们无法判断该类的哪个部分存在问题。但是可以说出来。

    注释掉该类的一半,然后重试。如果它有效,那么你注释掉的那一半就有问题。如果它不起作用,那么你没有注释掉的那一半有问题。无论哪种方式,注释掉其中有问题的部分,然后重试...

    这就像二分搜索。

    【讨论】:

    • 我添加了其余代码,我只是将对象保存到会话 Session["basket"] = new Basket();
    【解决方案2】:

    我发现了错误..

    序列化过程可能不喜欢事件:-/

    我必须只使用 InProc Session。

    【讨论】:

    • 您是否通过使用我的“二分搜索”方法发现了这一点?如果您尝试过,那么您会以这种方式发现这个问题。
    • 我使用了方法尝试错误。 :-) 会话序列化根本不喜欢事件。
    猜你喜欢
    • 2012-05-07
    • 2013-09-24
    • 2021-07-18
    • 2012-05-01
    • 2010-11-23
    相关资源
    最近更新 更多