Session_OnStart() does not fire on the first GET request - c#

I have a weird problem. Can't explain this inconsistent behavior.
Normally I would expect that the first GET request to load my default.aspx to fire the Session_OnStart() event. However, this happens only on the first page load after restarting the IIS. On all subsequent page loads (after clearing cookies), Session_OnStart() does not fire on the first GET request.
The page also makes two other POST requests from the client side through jQuery Ajax. Session_OnStart() does fire for BOTH of these requests on all subsequent page loads (again after clearing cookies).
This is a problem because SessionId is not being set on the first response, rather its being set twice on the subsequent responses to the POST requests. So the application ends up creating two SessionIds for each user. And again this does not happen on the first page load right after the IIS restart, which is the weird part.
it is an asp.net 3.5 website running on IIS 7.

Related

Problem with request and events fired in ASP.net Global.asax on a postback from a payment gateway on Chrome 80+

I have ASP.net web forms application that integrates with a certain payment gateway. After the payment gateway does its magic it posts back the response back to my site on to dedicated web page. The page accepts postback data and stores it in the database.
A very simple process that was working flawlessly up until Google released its Chrome v80 browser. Then in some instances, not always, only on these new versions of Chrome, some postback requests from the payment gateway started failing. All other browsers still work fine, even older versions of Chrome.
I suspected that the problem is with cookies and that new SameSite rule Google imposed in this new version of Chrome. I read about that issue and what to do to make my app support those Google changes, but it seems that the issue is not relevant to my problem because most of the time postbacks work just fine. I spent some time fiddling with it anyway, I even upgraded my web to .net Framework 4.8, but it didn't help.
By analyzing error logs I noticed that there is no content in the postback from the payment gateway sent back to my site. During the forensics, I implemented all request related event handlers in global.asax on my web site to track what is going on with requests. And what I found got me even more confused.
Normally, for all valid postback requests, the first event triggered is always BeginRequest and the others follow, ending with these three events:
EndRequest
PreSendRequestHeaders
PreSendRequestContent
But, in the failed postbacks, BeginRequest is not the first event fired. It is EndRequest, followed by the other two events mentioned above. Those three events have access to the correct postback content.
After those three events, BeginRequest is fired and all events that are supposed to go after it. But from BeginRequest on, there is no request content. It seems like the request's content is being reset or disposed of after those first three events, and a new HTTPRequest (or even HTTPContext) is initialized but without content.
I really do not understand what is going on and in week-long research, I could not find anything related to my problem. I tried all sorts of tricks to try to transfer the postback content form the first three events into the next BeginRequest, but with no success.
This is what I discovered so far:
a valid postback starts with BeginRequest event
an invalid postback starts with EndRequest event
for valid postbacks, the session cookie and all other cookies are available
for the failed postbacks, the session cookie and most of the other cookies are not available in the first three events (it smells like SameSite issue?) but they are available later in the rest of the events
in the failed postback, after the first three events, HTTPContext Items collection and local variables within global.asax are being reset
There are two facts that confuse me:
Problem is obviously related to something Google did to Chrome in the latest version, but why is it so inconsistently occurring? It would be obvious that there is something wrong with my app if it would fail always.
What the heck is going on with ASP.net request processing events in global.asax? How is it possible that the first event is EndRequest? I have never seen this behavior before.
Any piece of advice, hint or push in the right direction is welcome. Maybe I don't see something that is very obvious, so please, help me see it. If there is anything unclear in my description, do tell so that I try to clarify it.
EDITED:
After more investigation (read googling) and testing I was able to resolve the second issue, the EndRequest event triggering first. EndRequest is triggered first if an unhandled exception occurs before the BeginRequest event is fired. In my case, it was an exception within one of the HTTP Modules. After the exception reason was fixed there were no more issues with EndRequest event.
But now I'm tackling missing cookies in the failed requests, what probably seems to be the result of invalid cookie definition (SameSite=None, Secure not being applied correctly). In the production environment, cookies are being rejected when submit comes from the payment gateway. It works OK on the dev site, but not in the production.

Postback in Website and webapplication

I'm confused on how the postback works in website and web application because,
I have a button and in that I have given a sleep time for about 30 seconds and in another page on the same time when I try to do any activities like, click redirect etc.
In Web application the above scenario works without any issue.
In Web Site till the button event comes out the sleep time all the other activities will be hang up.
Please explain me on this.
Thanks in advance.
If Session state is enabled, requests within the session will be processed one by one. In your case, request is not completed until button handler comes out of sleep. Other requests are waiting until first request is completed.
To enable concurrent requests you must specify EnableSessionState="ReadOnly" in ASPX file which contains button. Or just disable Session state in webconfig.
<%# Page EnableSessionState="ReadOnly" MasterPageFile="..." CodeBehind="xxx.cs" Inherits="xxx" %>

Re submission restriction in c#

How to restrict previous , operation after re submission. example if I click on one button if I resubmit (f5) that page will refresh , whatever we previously clicked button will execute once again. so I don't want to execute once again. So can you help me to solve this problem ?
You should read about PRG pattern:
Post/Redirect/Get (PRG) is a web development design pattern that
prevents some duplicate form submissions, creating a more intuitive
interface for user agents (users). PRG implements bookmarks and the
refresh button in a predictable way that does not create duplicate
form submissions.
More about this here.
Short explanation of the way it works:
When a web form is submitted to a server through an HTTP POST request,
a web user that attempts to refresh the server response in certain
user agents can cause the contents of the original HTTP POST request
to be resubmitted, possibly causing undesired results, such as a
duplicate web purchase. To avoid this problem, many web developers use
the PRG pattern1 — instead of returning a web page directly, the
POST operation returns a redirection command.
You could consider redirecting the user to another web page, so that the subsequent request is made using GET.
The goal here is that the act of loading the submission action page is what causes the browser to resubmit on refresh. After all, you are literally requesting that same submission action a second time. By redirecting to another page, your request will now be done using GET, and the page that is loaded will not be the one that performs submit logic.
This is also known as the Post/Redirect/Get pattern.

Invalid viewstate error on postback

I am getting the following error when the user tries to submit a form, it only happens sometimes... Not sure how to resolve or what the root cause could be. Any help is appreciated. Please see below for screenshot..
Framework 4.0, IIS7
http://s12.postimage.org/69txogmwr/Untitled.png
Things that I have seen cause this:
machinekeys out of sync in a webfarm
page loads slow and the user posts back before it's finished
page sits idle after partial postbacks and the app pool is recycled
page sits idle, new code is deployed for page/controls, first postback dies due to mismatched controls

Session_End code on browser close

I have a method I need to run on Session_end. Is there any way I can ensure the code runs when a user closes his browser? This may be a dup queston. I saw one response doing a call to ajax unload or something, but I don't want this to fire everytime a user navigates away from a page, just when they close their browser.
Thanks,
~ck
Simple answer: You can't control user's browser. The AJAX solution you mentioned is the closest you can achieve (without a plugin/custom client.) Imagine some Web site could track every time you opened and closed your browser window. Don't you think it would be a privacy issue?
The truth lies in the stateless nature of HTTP. The Web server is out of the picture as soon as it finishes sending the response to the client. After that, all you can rely on is a client side script (which only executes because the client wants it to; and it can easily choose not to run scripts.)
Session_end is unreliable. No matter what you do.
Session_end only fires when you are using inprocess session. If you are using a session state server or SQL session, session_end does not fire.
When using in process session, session_end only fires if you have stored something in session. If you aren't using session, session_end will never fire.
If you are using session and the user closes the browser, session_end will fire when the users session times out. While it will have some of the same settings as the original session, this event will not be tied to a browser since it is the worker process detecting the session timeout and firing the session_end process.

Categories