Our ASP.Net MVC application is hosted on Azure. recently, one of our user reported issue that he is able to see data related to other user. we tested this on our 3-4 laptops and could able to replicate. this scenario happened 2-3 times but not frequently. It is strange. we were still not able to find out root cause of this issue. we are not using output caching technique. we are using Forms Authentication and session timeout kept open for 30 minutes only. we also didn't use any static variable to store session.
On Azure, we have traffic manager profiles implemented. there 2 instances of these application exists and priority was set accordingly so as to up one instance when other gets down.
when checked code, We found below code from Global.asax but don't know exact usage of this code. it could be issue but not sure 100%. when debugged, this gets called every time when action is executed.
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Cache["RecycleCheck"] == null)
{
HttpContext.Current.Cache.Insert("RecycleCheck", "1", null, DateTime.UtcNow.AddDays(2), System.Web.Caching.Cache.NoSlidingExpiration);
appendLogFile("Recycle Took Place");
}
if (HttpContext.Current.Session == null || Session["CurrentUser"] == null) return;
HttpContext.Current.User = (CustomPrincipal)Session["CurrentUser"];
}
How session gets mixed? is there bug in Azure IIS Server or we are missing something in our code? how to avoid session mixing?
Related
I have sample webapp deployed to Azure. The app cached a variable using MemoryCacheEntryOptions to store a value (from database) which expire in 5 minutes.
However after 5 minutes via Chrome debugging tool, I still can query the cache, the cache value expected to be empty or whatever the new value which currently stored updated in the database.
I even tried to clear cache in the web browser, but cache seem still retain the previous value.
However when I restart the web site, and open the web app again the cache value is no longer exist.
Would any setting in Azure might affect the cache expiry?
private readonly MemoryCacheEntryOptions _cacheEntryOptions;
protected CacheService(IMemoryCache memoryCache)
{
_ memoryCache = memoryCache;
_cacheEntryOptions = new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300)
};
}
Debugging the behavior of a web application is notoriously hard, as all you got to control it is the Browser - and you never get exclusive access.
Even if you did not refresh the page, any number of things might have queried the server. The culprits start around "any search engines webcrawler" and end around "somewhat aggressive security tools" (because some viruses might use web servers). You could try a way shorter timeout. But ideally you want to have both the Server and the client you access it with run in separate virtual machines, which are only connected via the Hypervisor. That way you can be certain nobody is interfering.
I currently maintain a nearly 3 years old ASP .Net MVC website, the application is running above IIS (now in IIS 7) and using ASP .Net 4 Framework. It used by client almost everyday and had a lot of upload-download file transaction. It also use ELMAH as Unhandled Exception Handling. The application running well until a few past month, there are a lot of report from user that they cannot do download the file, but without any error message, the download process just not doing anything while there is also no log in Browser Console. After doing several checking, all menu that have download function are using http response
Response.Clear();
Response.Cache.SetCacheability(HttpCacheability.Private);
Response.Expires = -1;
Response.Buffer = true;
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Length", Convert.ToString(file_in_bytes.Length));
Response.AddHeader("Content-Disposition"
, string.Format("{0};FileName=\"{1}\"", "attachment", fileName));
Response.AddHeader("Set-Cookie", "fileDownload=true; path=/");
Response.BinaryWrite(hasil);
Response.End();
And nothing seems wrong (there are no Compile or Runtime Error in Development Server). We've also checked Elmah's log, but there no related error message appear in there. And This problem is temporarily disappear after our Server Management Team do Recycling the Application Pool in IIS.
This Web is also share Application Pool with another web, and when that error occurred, both application are affected, only the download function that affected, the other function like data retrieval from database, insert/edit/delete data is working fine.
I also checked the Web Server Event Viewer but there is nothing error in there. The very odd thing for us is that this error temporary disappear after we Recycling the Application Pool and after several days or weeks or months the error suddenly appear again.
Is there any log that we've missed to trace? or perhaps there is wrong with the Download code? And why its temporarily fixed after Recycling Application Pool?
Another Note : The data that need to be download by user is at average 500kb to 2MB in zip format contains several PDF files
Update : After few more hour investigating, I found that this web application using different method to Download, some are using the Http.Response like above code, and some are use FileContentResult as return value. But both using jquery.FileDownload in client-side. I also found this method in several Controller that has Download File method in this app,
private void CheckAndHandleFileResult(ActionExecutedContext filterContext)
{
var httpContext = filterContext.HttpContext;
var response = httpContext.Response;
if (filterContext.Result is FileContentResult)
{
//jquery.fileDownload uses this cookie to determine that
//a file download has completed successfully
response.AppendCookie(new HttpCookie(CookieName, "true")
{ Path = CookiePath });
}
else
{
//ensure that the cookie is removed in case someone did
//a file download without using jquery.fileDownload
if (httpContext.Request.Cookies[CookieName] != null)
{
response.AppendCookie(new HttpCookie(CookieName, "true")
{ Expires = DateTime.Now.AddYears(-1), Path = CookiePath });
}
}
}
Actually I'm not really sure is that method related to this error or not, but it is called in a method that override System.Web.MVC.Controller OnActionExecuted, and it contain the line off adding Cookie for file download if using FileContentResult or delete Cookie if is not using FileContentResult and file Download Cookie is exists. It is Possible if Cookie is Accidentally not deleted / cleared after it created? And because the download method is frequently called by nearly 100 user everyday, it is possible that the Cookie is pile up and cause IIS Worker Process Crash?
I've also checked some references about Cookie and its relation to IIS Session State (My Apps using In-Proc State). Am I Close? Or did I miss something?
Is there a reason why Response.Buffer is set to true? When buffering is enabled, the response is sent only after all processing is completed. Can you disable it by setting to false and see if this works? This could be the reason for having to recycle the app pool. You can also check if you are facing these issues - Help link
On my localhost server Session["Culture"] variable always store the proper value.
But on my external server, the same session variable (Session["Culture"]) sometimes lose value and become null. Why it is happen? And how to resolve it?
Part of a global.asax.cs file:
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
CultureInfo ci = (CultureInfo)this.Session["Culture"];
if(ci == null){
//breakpoint
}
}
}
EDIT:
It is obvious that session cannot be shared between server A and server B. My problem is rather different - in a nutshell- the same application, but:
1) on server A (localhost) Session["Culture"] works properly and it always store some information.
2) on server B (external) Session["Culture"] work nice but always after random time lose value and become null
In-process session state is subject to being cleared any time, as sessions are ended when the appdomain is recycled.
You can mitigate this some by using an external session storage mechanism, such as the state service, or a database provider. You can also build your own session state provider.
However; you should still treat session state as only somewhat less volatile than cache, if you want it to be robust; always check for null, and reset the values if so.
If sessions are expiring that quickly on one server, I would look into why that might be. Something may be causing recycles improperly.
Addition: I see you are using multiple servers; in-process session state also cannot handle this. The above advice can help there, too.
I have a process that involves a few .aspx pages. Fill out some info in one, hang on to it, move to another page that has an iframe on it, upload some documents in the iframe via a web service to a server, hang on to the list of documents and the status of the upload and then, on a third page, do something else that involves saving all the data to a database.
Before moving from page 1 to page 2, I put some data in Session variables. On page 2, the data is retrieved and displayed, some more data is put into Session variables during the process of uploading the files from within the page in the iframe on page 2 then, on page 3 the data is retrieved from Session and written to the database.
On a test server this all works perfectly. On a live server, I keep getting (random) 'object not set to a reference' errors - which seem to be reporting that the session variables have disappeared.
My understanding is that, within .aspx pages ...
HttpContext.Current.Session["myvariable"]
Session["myvariable"]
are, effectively, the same thing. I am setting my session variable just using ...
Session["Variable1"] = "fred";
Any ideas why (randomly, sometimes the process works fine on the live server) I seem to be losing my Session variables?
This is a web site as opposed to a web application. Developed in VS2010 using Framework 4.0
There can be various reasons why you are loosing the session.
Some of them are:
Your sessionState timeout has expired
You update your web.config or other file type that causes your Application Domain to recycle like files in folder App_Data
Your Application Pool gets recycled
You update your site with a lot of files just by doing copy and paste physically, and ASP.NET will automatically recycles the session.
If you are not sure of the reason you can do event logging why application pool is getting recycled. May be you will come to know about the reason and depending upon that you can take preventive measures.
For Logging you can write following code block on Application_End
public void Application_End()
{
HttpRuntime runtime = (HttpRuntime)typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, null, null, null, CultureInfo.InvariantCulture);
if (runtime == null)
return;
string shutDownMessage = (string)runtime.GetType().InvokeMember("_shutDownMessage", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null, CultureInfo.InvariantCulture);
string shutDownStack = (string)runtime.GetType().InvokeMember("_shutDownStack", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null, CultureInfo.InvariantCulture);
//Do Logging as per your need and implementation
//Logging.Write(TraceEventType.Error, shutDownMessage, shutDownStack);
}
The is a good posiblity you save non serializable objects in you session variables and keep your session out of proc on your production server (load balancing?). Check if you objects are seriablizable and if not make them serializable.
What happens is your live server is recycling its application pools, which basically resets the memory used for applications. Normally a timeout can be set, but if the application pool recycles, this will reset your session.
The solution is to use SQL server for your session state.
Try this: http://support.microsoft.com/kb/317604
Supplemental Link: http://www.codeproject.com/Articles/104082/Configuring-ASP-session-state-on-SQL-server
If you are hosting with a larger public host, they have probably already prepped their SQL to handle session states, and you should be able to just make the change in your web.config file to use SQL session state.
Ciao
There is one more condition where sessions can lose its value.
You can use Fiddler tool to trace out this problem.
The most condition can be found when you some element like source not found in solution. At that moment server will try to reload that unfounded or lost object by restarting the project. Restarting the project will result in resetting all session objects.
Thanks.
Some quick details:
I'm running ASP.NET 4.0.30319.0 on IIS6. I've been hosting a website that contains a ReportViewer for quite some time now (~3 years). In April, I upgraded to the 4.0 runtime, and things ran smoothly for a couple of months.
Now, I'm suddenly starting to see quite a Session Timeout exceptions occur on the pages hosting the ReportViewer. The Event Viewer has many many of these events logged, and it's rather hit or miss when it comes to actually being able to view the page. Hitting the page once, you can see the generated report. Refresh, and the error occurs. Refresh again and it returns...
I've scoured many forums trying to figure out the issue - most seem to recommend changing SQL server settings (which I'm not using), changing the AsyncRendering="False", changing the Application Pool settings, or the timeout. I'm reluctant to change any of these, as it has worked only a week ago, without this issue.
Short of a Windows Update, or someone making a change to the server without my knowledge, I'm out of ideas...
Update
I've tried increasing the maximum virtual memory, in the app pool, which didn't work.
I have almost the same problem, after upgrading to .NET 4.0 and Report Viewer 2010. I did both upgrades at the same time, now I'm not sure who's to blame. In my case, refresh does work, but the users keep the page open during the night, then click on refresh the next morning, when the session is already lost. Our app pool recycles every night.
I believe the report viewer is supposed to keep the session alive, but it doesn't. There's no request of any kind from the report viewer. It then loses it's stored state when the session ends, either by session expiration or app recycling. I'm also using InProc, I tried to change it, but the report viewer did not work with State Server. I will try again at a later time, to move away from InProc.
See my similar question.
I haven't put it into production yet, but I gave the aspx pages with the reports a custom page to derive from, and I will check there if the session has actually timed out. It basically reloads the report page, instead of doing postback where it expects the session.
if (Context.Session != null)
{
//Tested and the IsNewSession is more advanced then simply checking if
// a cookie is present, it does take into account a session timeout, because
// I tested a timeout and it did show as a new session
if (Session.IsNewSession)
{
// If it says it is a new session, but an existing cookie exists, then it must
// have timed out (can't use the cookie collection because even on first
// request it already contains the cookie (request and response
// seem to share the collection)
string cookieHeader = Request.Headers["Cookie"];
if ((null != cookieHeader) && (cookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
{
Response.Redirect(Request.Url.ToString());
}
}
}