2009-08-13 46 views
1

我正在修复大量使用会话来跟踪每页数据的ASP.NET应用程序。其中一个问题是会话在页面之间流血。使用像ViewState这样的会话

ViewState的将是一个更好的解决办法,除非:

  • 的数据是不可序列
  • 有太多的数据每次回发

所以我想被发送来回:

  • 为会话数据创建页面密钥(即在隐藏字段中粘贴一个随机GUID)
  • 从一个废弃的页面过期数据,即使整个会话活跃

是否有到期部分会话的数据的好方法吗?

+0

有点信息将是有益的。您是否试图为每个页面存储相同的数据结构,或者每个页面有唯一的数据结构?为什么会话数据在用户离开后闲逛会出现问题? – 2009-08-13 13:32:16

+0

@Christian Hayter他的问题意味着多个页面使用相同的会话密钥。因此,针对页面A的数据将留在会话中供页面B查找。 – AaronSieb 2009-08-13 13:51:26

+0

AaronSieb是正确的。 – Korey 2009-08-13 15:43:41

回答

2

下的临时存储位置可供选择:

  1. 会议。这跟随用户并使用cookie。它可以配置为使用URL参数来检索。会话也可以配置为存储在Web服务器,SQL Server或状态服务器上的进程(inproc)中。 InProc可以存储任何数据类型,但其他类型需要可序列化的类型。
  2. 缓存。存储在缓存中的数据可供任何用户在会话中使用。它与会话类似,因为对象可以通过密钥进行检索。缓存的一个更好的功能是可以控制事物的存储时间,并且可以在事件过期时使用事件。你可以在这里存储任何东西,但是你可能会遇到在webfarm中使用它的问题。
  3. HttpContext。这是针对当前请求的范围。请记住,请求可以是web服务调用,调用获取HTML的网页或调用返回图像的服务。任何东西都可以存储在这里。
  4. ViewState。视图状态的范围是一个页面。必须是可序列化的。

您可能需要检查缓存。如果您使用的是网站农场,它不起作用,但您可以使用某种类型的GUID作为您映射回会话的密钥。

+0

如果我可以保证缓存可能会在会话持续20分钟左右的时间内完成。 – Korey 2009-08-13 15:34:32

+0

这里是我使用的缓存代码: Cache.Insert(key,value,null,System.Web.Caching.Cache.NoAbsoluteExpiration,new TimeSpan(0,20,0),System.Web.Caching.CacheItemPriority.NotRemovable , 空值); – Korey 2009-08-14 20:54:29

+0

CacheItemPriority.NotRemovable阻止Cache由于内存压力而删除数据。 – Korey 2009-08-14 20:55:02

0

也许在每个页面!IsPostBack或通过基本页面,您可以清空所有对与该页面无关的会话数据的引用。每次用户转到站点中的其他页面时,这会使数据“过期”。

如果用户离开网站或处于非活动状态,则在会话过期之前可以做的事情不多,但在这种情况下,每个用户只有一页会话数据。

+0

我确实希望允许查看多个页面(同一页面,但具有不同的请求数据)。我不希望一个页面自动销毁另一个会话数据,我只是希望它能够过期。 – Korey 2009-08-13 15:35:34

1

我可能会做这种方式:

  1. 创建一个对象来存储你想成为特定页面的状态信息。如果不同的页面需要不同的信息,请创建多个类。
  2. 将此对象存储在单个会话密钥中:Session [“PageSpecific”];例如。
  3. 创建一个继承自System.Web.UI.Page的类。
  4. 在基类的OnLoad事件中,如果页面未执行回发,请清除会话密钥。
  5. 创建并调用可重载的方法来填充会话对象。
  6. 不是从每个页面的System.Web.UI.Page继承,而是从新的基类继承。

像这样的东西(警告:空气代码可能包含语法错误):更多

public class PageBase 
    : System.Web.UI.Page 
{ 
    protected overrides OnInit(System.EventArgs e) { 
     base.OnInit(e); 

     if(!this.IsPostBack) { 
      Guid requestToken = System.Guid.NewGuid(); 
      ViewState["RequestToken"] = requestToken; 

      Session["PageSpecific" & requestToken.ToString()] = InitializePageSpecificState(); 
     } 
    } 

    protected virtual object InitializePageSpecificState() { 
     return new GenericPageState(); 
    } 

    //You can use generics to strongly type this, if you want to. 
    protected object PageSpecificState { 
     get { 
      return Session["PageSpecific" & ViewState["RequestToken"].ToString()]; 
     } 
    } 
} 
+0

这与以前的答案有相同的问题。我的问题可能不够清楚。 某些用户可能在多个选项卡中查看Default.aspx,并使用不同的请求数据(甚至相同)。我希望每个人都有自己的服务器端存储空间。 – Korey 2009-08-13 15:42:15

+0

@Korey这将是一个好东西编辑到您原来的问题。它也很容易解决:在初始加载时生成某种形式的令牌(如Guid)。将其附加到会话密钥(会话[“PageSpecific”&requestToken])。将密钥存储在ViewState中。 – AaronSieb 2009-08-13 16:30:05

+0

@Korey允许多个选项卡打开的主要困难是您无法从请求中清除会话,直到整个会话过期为止......这可能会也可能不会成为问题,具体取决于您的大小用户群。 – AaronSieb 2009-08-13 16:35:45