会话变量由于某种原因丢失
我尝试建立一个电子商店。在每个项目旁边,我都有一个 asp:imagebutton
当单击此图像按钮时,我将检查会话变量 session["basket"]
是否存在,如果不存在,则我在列表(实体类)中添加值,然后在会话中添加此列表。
如果会话不为空,那么我将会话中的值检索到列表中并更改列表,然后将列表添加回会话。
问题:
由于某种原因,我突然丢失了会话变量。我检查了我的手表(时间),它是不可预测的,有时需要不到 1 分钟,有时 3 分钟,有时 5 分钟等等......
为什么我会丢失会话变量?
我用谷歌搜索,发现 - 如果您使用 Response.Redirect
- 没有错误参数,或者如果您在 UpdatePanel
等中,则可能会发生这种情况。
我'我暂时失去了同一页面中的变量。
整个想法是放入一个会话变量中,并在第二个 aspx
页面中签出并检索会话变量...但这并不总是有效,因为大多数情况下会话变量会变空。有时它会起作用。
有人可以建议吗?我需要检查什么以及在哪里检查? 在某些网站页面(谷歌)中,他们建议使用缓存,但缓存是基于应用程序的,因此每个人都会检索相同的值。
在我的页面中,任何用户(经过身份验证的或任何匿名用户)换句话说,任何没有登录的用户都应该能够订购(我将发送发票以预先付款)....
我没有使用 webfarm,也没有使用 web Garden...我刚刚检查了 IIS - 网站 - 会话状态 - 正在处理,cookie 设置 = 使用 cookies,名称 = asp.net_sessionid,超时 = 20....
请建议?
它是 C#
、ASPX 3.5
、IIS7.5
我的 ASPX 页面中没有 PAGE_LOAD。
// 我唯一放置 sessoin=null 的地方是链接按钮,其余的我不会在 session["basket"] 中放置 null....
protected void lnkDeleteAllSelected_Click(object sender, EventArgs e)
{
Session["Basket"] = null;
ReloadBasketItems();
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//System.Diagnostics.Debugger.Break();
lvJuridisch.ItemDataBound += new EventHandler<ListViewItemEventArgs>(this.lv_ItemDataBound);
lvJuridisch.DataBound += new EventHandler(lv_DataBound);
}
imgButtonAddtoBasket ->在 asp:listview 中定义为 asp:imagebutton
protected void imgButtonAddtoBasket_Click(object sender, ImageClickEventArgs e)
{
ListViewDataItem lvi = ((sender as ImageButton).NamingContainer) as ListViewDataItem;
DataKey currentDataKey = (lvi.NamingContainer as ListView).DataKeys[lvi.DataItemIndex];
WebShopInfo SingleItem = new WebShopInfo();
SingleItem.cd_type_pub = currentDataKey[0].ToString();
SingleItem.no_pub = currentDataKey[1].ToString();
SingleItem.no_suite_pub = Convert.ToInt32(currentDataKey[2]);
SingleItem.cd_langue = Convert.ToChar(currentDataKey[3]);
SingleItem.lb_titre_red = (lvi.FindControl("HiddenfieldProductRed") as HiddenField).Value;
SingleItem.m_price = Convert.ToDecimal((lvi.FindControl("hiddenField_M_Price") as HiddenField).Value);
SingleItem.nm_price = Convert.ToDecimal((lvi.FindControl("hiddenField_NM_Price") as HiddenField).Value);
SingleItem.mt_pourc_tva = Convert.ToDecimal((lvi.FindControl("hfBTW") as HiddenField).Value);
List<WebShopInfo> lws = new List<WebShopInfo>();
if (Session["Basket"] == null)
{
//Session is empty so add listview to the session....
//Session.Timeout = 20; -- I tried this but this is not working too...
lws.Add(SingleItem);
Session["Basket"] = lws;
}
else
{
//Session is not empty so get asp:listview from the session.
lws = Session["Basket"] as List<WebShopInfo>;
WebShopInfo wsi = lws.Where(a => a.cd_type_pub == SingleItem.cd_type_pub &&
a.no_pub == SingleItem.no_pub &&
a.no_suite_pub == SingleItem.no_suite_pub &&
a.cd_langue == SingleItem.cd_langue).SingleOrDefault<WebShopInfo>();
if (wsi != null)
lws.Remove(wsi);
if (SingleItem.Count > 0)
lws.Add(SingleItem);
Session["Basket"] = lws;
}
ReloadBasketItems();
}
I try to setup a E-shop. Next to every item I've an asp:imagebutton
when this imagebutton is clicked I'm checking whehter the session varialbe session["basket"]
exists or not if not then I add the values in a list (entity class) and I add this list in the session.
if the session is not empty then I retrieve the values from session into List and change the list and then add the list back to session.
Issue:
For some reason I loose the session variable, suddenly. I checked on my watch (time) and it's unpredicatble sometimes it takes less than 1 minute, sometimes 3 minutes and sometimes 5 minutes etc....
why do I loose the session variable?
I googled and I've found - it can happen if you use Response.Redirect
- w/o false parameter, or if you're in an UpdatePanel
etc.
I'm loosing the variable in the same page for the moment.
The whole idea is put in a session variable and do checkout and retrieve the session variable in second aspx
page... but this is not always working, because most of the case the session variables becomes empty. And sometimes it works.
can someone advice ? what and where do I need to check?
In some website pages (google) they advice to use caching, but caching is application based, so everybody will retrieve the same value.
In my page any user (authenticated or anynomous user) in other words any user without login should able to order (I'll send invoice to pay upfront)....
I''m not using webfarm, nor web garden... I just checked the IIS - website - session state - It's in process, cookie settings = use cookies, name = asp.net_sessionid, time-out = 20....
please advice?
It's C#
, ASPX 3.5
, IIS7.5
I DON't have PAGE_LOAD in my ASPX page.
// the only place I put the sessoin=null is a linkbutton, for the rest I don't put null in session["basket"]....
protected void lnkDeleteAllSelected_Click(object sender, EventArgs e)
{
Session["Basket"] = null;
ReloadBasketItems();
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//System.Diagnostics.Debugger.Break();
lvJuridisch.ItemDataBound += new EventHandler<ListViewItemEventArgs>(this.lv_ItemDataBound);
lvJuridisch.DataBound += new EventHandler(lv_DataBound);
}
imgButtonAddtoBasket -> is defined as asp:imagebutton in the asp:listview
protected void imgButtonAddtoBasket_Click(object sender, ImageClickEventArgs e)
{
ListViewDataItem lvi = ((sender as ImageButton).NamingContainer) as ListViewDataItem;
DataKey currentDataKey = (lvi.NamingContainer as ListView).DataKeys[lvi.DataItemIndex];
WebShopInfo SingleItem = new WebShopInfo();
SingleItem.cd_type_pub = currentDataKey[0].ToString();
SingleItem.no_pub = currentDataKey[1].ToString();
SingleItem.no_suite_pub = Convert.ToInt32(currentDataKey[2]);
SingleItem.cd_langue = Convert.ToChar(currentDataKey[3]);
SingleItem.lb_titre_red = (lvi.FindControl("HiddenfieldProductRed") as HiddenField).Value;
SingleItem.m_price = Convert.ToDecimal((lvi.FindControl("hiddenField_M_Price") as HiddenField).Value);
SingleItem.nm_price = Convert.ToDecimal((lvi.FindControl("hiddenField_NM_Price") as HiddenField).Value);
SingleItem.mt_pourc_tva = Convert.ToDecimal((lvi.FindControl("hfBTW") as HiddenField).Value);
List<WebShopInfo> lws = new List<WebShopInfo>();
if (Session["Basket"] == null)
{
//Session is empty so add listview to the session....
//Session.Timeout = 20; -- I tried this but this is not working too...
lws.Add(SingleItem);
Session["Basket"] = lws;
}
else
{
//Session is not empty so get asp:listview from the session.
lws = Session["Basket"] as List<WebShopInfo>;
WebShopInfo wsi = lws.Where(a => a.cd_type_pub == SingleItem.cd_type_pub &&
a.no_pub == SingleItem.no_pub &&
a.no_suite_pub == SingleItem.no_suite_pub &&
a.cd_langue == SingleItem.cd_langue).SingleOrDefault<WebShopInfo>();
if (wsi != null)
lws.Remove(wsi);
if (SingleItem.Count > 0)
lws.Add(SingleItem);
Session["Basket"] = lws;
}
ReloadBasketItems();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
听起来你的应用程序域正在被回收。您的
web.config
compilation
元素是否设置为debug
模式?在调试模式下,ASP.NET 每 15 次动态编译就会重置应用程序域。发生这种情况时,如果您的会话存储在内存中(InProc
模式 - 默认),它们将会丢失。仅供参考,只要您的站点上发生文件更改,例如编辑 ASPX 文件、正在生成的图像或 web.config 更改,就会发生动态编译。
因此,要么将站点置于发布模式 (
),要么将中的
,或使用非易失性会话存储模式 - 例如 SQL 会话状态。numRecompilesBeforeAppRestart
值从 15 增加web.configSounds like your appdomain is being recycled. Is your
web.config
compilation
element set indebug
mode? In debug mode, ASP.NET resets the appdomain every 15 dynamic compilations. When that happens, if your sessions are stored in memory (InProc
mode - the default), they'll be lost.FYI, a dynamic compilation will occur whenever a file change happens on your site, like you editing an ASPX file, or an image being generated, or a web.config change.
So either put the site into Release mode (
<compilation debug="false" ... />
), or increase thenumRecompilesBeforeAppRestart
value from 15 inweb.config
, or use a non-volatile session storage mode - e.g. SQL Session State.你是否只丢失了那个特定的变量? - 如果是这样,那么可能是您的代码的某些部分正在执行此操作。
如果您丢失整个会话对象,那么除非您的会话超时,否则另一个原因是,如果您在服务器上使用 inproc 会话状态并耗尽内存 - 这会回收您的工作进程,导致您丢失会话值。检查您的事件日志以查看是否属于这种情况。
Are you losing just that particular variable? - If so, then it is probably some part of your code that is doing this.
If you are losing the entire session object, then unless your session has timed out, the other reason is that if you are using inproc session state at your server and ran out of memory - this recycles your worker process causing you to lose the session value. Check your event log to see if this is the case.
您会惊讶地发现会话在幕后使用缓存!
看一下下面的内容(您会发现有关会话问题的所有常见问题):
http://mmtripathi.blogspot.com/2008/09/session-lost-problem-after.html
http://zeeshanumardotnet.blogspot.com/2009/07/why-sessions -are-termminatedloss.html
http://classicasp.aspfaq.com/general/why -won-t-my-session-variables-stick.html
you will be surprised to know the behind the scene the session uses the cache!
have a look at the below(you will find all the common problem about session issue):
http://mmtripathi.blogspot.com/2008/09/session-lost-problem-after.html
http://zeeshanumardotnet.blogspot.com/2009/07/why-sessions-are-terminatedloss.html
http://classicasp.aspfaq.com/general/why-won-t-my-session-variables-stick.html
mesut:
老实说,会话内存可能非常不稳定。如果应用程序出现故障,您可以松开它,或者像您所说的那样,如果用户的会话重新启动,您可以松开它。通常,Asp.Net 的选项是将数据存储在:
ViewState(存储为可由您的代码隐藏访问的加密文本)
Session内存(本质上是一本字典,但如上所述,有一点
易失性)
ASP.Net 的状态服务(将值存储在单独的
过程。注意服务器场场景)
Cookies
Cache
Url 参数
这些方法中的每一种都在性能方面有所权衡,内存,或依赖于用户的环境。我会尝试一种不同的方法,看看这对你来说是否更可靠。
mesut:
Honestly Session memory can be very volitile. If the application goes down you can loose it, or like you said, if the user's session gets restarted you can loose it. Generally the options for Asp.Net are to store data in:
ViewState (stored as encrypted text accessable by your code-behind)
Session Memory (essentially a dictionary, but as above, a little
volatile)
ASP.Net's State Service (which stores the values in a separate
process. watch out for server farm scenarios)
Cookies
Cache
Url Parameters
Each of these methods has a trade-off in terms of performance, memory, or being dependent on a user's environment. I would try a different method and see if that is more robust for you.
检查您是否使用在多个网站/应用程序之间共享的
应用程序池
,如果您与其他网络应用程序/网站共享同一个AppPool
- 切换到单独的应用程序池
。最好的方法是使用基于服务器的会话状态,在这种情况下您可以忘记此类问题。请参阅如何:配置 SQL Server 以存储 ASP.NET 会话状态
Check out whether you are using
Application Pool
which is shared across multiple web sites/applications, if you are sharing the sameAppPool
with an other web application/site - switch to separateAppPool
.The best way is to use server-based session state, in this case you can forget about such issues. See HOW TO: Configure SQL Server to Store ASP.NET Session State