回发后抓住物品

时间:2009-11-09 20:14:21

标签: asp.net data-structures

我有一个ASP.NET Web应用程序,我希望能够从主列表中获取项目并将它们临时存储到其他四个列表中。 “其他”列表需要在后退后存活,以便可以向其添加更多项目。你建议去哪个方向?

我曾想过使用存储在内存中的通用列表,暂时将这些项存储到数据库中并在PostBack上调用它们,或者将它们存储到viewstate中,但我觉得有一些解决方案我是遗失可能更容易或更好。

6 个答案:

答案 0 :(得分:1)

我建议的第一件事是看你是否可以消除在回发中保持状态的需要。

如果你不能这样做(ViewState因某些原因(如带宽限制或需要数据保存而不适用,即使没有从服务器表单回发),我建议考虑使用Session。您可以随时配置会话状态以使用SQL Server数据库后端,而无需担心更改源代码。

答案 1 :(得分:1)

乔希很好地阐述了各州。我建议像他说的更小的列表将使用会话状态。使用数据库会有点混乱,因为您必须维护这些临时表并担心对表的多会话访问。同样,缓存也有同样的问题。 Viewstate为您提供额外的客户端流量和不安全的数据。因此,如果您在低流量服务器上谈论不到几千个实例,那么会话就可以了。

为了使会话更易于使用(并且您可以使用缓存和应用程序状态执行此操作),请设置一个管理列表的容器对象。

//To use it in your page, you can easily access it via: 

ListManagerContext.Current.MasterList.Add(4);


[Serializable]
public class ListManagerContext
{
    public List<int> MasterList { get; set; }
    public List<int> SubList1 { get; set; }
    public List<int> SubList2 { get; set; }
    public List<int> SubList3 { get; set; }


    /// <summary>
    /// Key used for the list manager context session variable.
    /// </summary>
    public const string ListManagerContextKey = "ListManagerContext";

    /// <summary>
    /// Gets the current ListManagerContext for this session. 
    /// If none exists, it returns a brand new one. 
    /// </summary>
    [XmlIgnore]
    public static ListManagerContext Current
    {
        get
        {
            HttpContext context = HttpContext.Current;

            if (context != null && context.Session != null)
            {
                ListManagerContext data = null;
                if (context.Session[ListManagerContextKey] == null)
                {
                    data = new ListManagerContext();
                    context.Session[ListManagerContextKey] = data;
                }
                else
                    data = context.Session[ListManagerContextKey] 
                                  as ListManagerContext;

                return data;
            }
            throw new ApplicationException("
                  No session available for list manager context.");
        }
    }
}

答案 2 :(得分:0)

数据库Idea可能很差(假设您没有处理大量数据)。

也许你最好的方法是将主列表存储在ViewState中,让其他列表成为第一个列表的索引列表。

答案 3 :(得分:0)

列表应自动存储它们在视图状态中的值。如果他们不这样做,您可能需要为这些控件打开视图状态。

如果您手动想要使数据在往返过程中保持不变,您可以将它们存储在会话中或自己存储在视图状态中。从技术上讲,视图状态最有意义,但是如果有大量数据,它可以使视图状态非常大并且需要很长时间才能进行往返。会话的唯一问题是,您必须确保在离开页面后清除它。

不要使用数据库,这不是它的用途。

答案 4 :(得分:0)

您可以将列表存储在ViewState或Session中,并将其分配给属性。这是使用通用字符串列表的简单示例,但可以是任何可序列化类型。

private List<String> MyTempList
{
   get{return Session["mylist"] as List<String>;}
   set{Session["mylist"] = value;}
}

protected void Page_Load(object source, EventArgs e)
{
  if(!IsPostBack)
  {
     MyTempList = new List<String>();
  }
  else
  {
     MyTempList.Add("Something");
  }
}

答案 5 :(得分:0)

所有这些都是选择,所有都有自己的利弊:

<强>数据库:

在数据库中存储项目是一个相当简单和一致的选项。您必须担心对数据库进行往返调用,但至少您有一个集中的位置来记录可以轻松扩展Web负载的数据。但是,如果这是短期数据,那么您将不得不担心清理数据库,因为它可能开始变得难以处理。

<强>会话/高速缓存:

会话为内存存储提供了快速解决方案,但如果数据量非常大,则扩展可能会出现问题。您在内存中存储的信息越多,并发用户的容量就越少。此外,如果您开始添加多个Web服务器,那么您将不得不查看某种会话状态服务器,以确保用户不会自发地丢失其会话。

缓存基本上具有相同的优点/缺点,除了必须确保使缓存项过期以及管理并发问题之外还有额外的复杂性。

同样,这些都是易于实现的解决方案,但在重负载或大量数据下也不能扩展。

<强>视图状态:

Viewstate也是一种易于实施的解决方案,可以减轻服务器和客户端的负担,但可能会导致最终用户的加载时间更长。此外,重要的是要记住ViewState可能被黑客入侵,因此如果担心安全问题,那么您需要采取额外的预防措施来确保数据的完整性。

<强>结论:

总而言之,找出您想要完成的任务并选择最适合您需求的解决方案。将它推到一些抽象层后面就像一个界面,这样你以后就可以轻松地改变细节了,然后你就不必担心了。这一切都是为了了解哪些在你的特定场景中最有效。