I would like to make a call to the underlying backend just one time when user first initiates a user session. While the session is up, the same call shall never be made again. Do I just create a singleton tied to the particular session or is there a better way to do this?
You can place the method call in the global.asax Session_Start event.
List of available events is listed here.
You can always use the Begin_Session Session_Start method in the global.asax. This will fire only once and only at the beginning of the session. It will fire before any authentication occurs, though.
Edit: Begin_Session? Sorry. Code bleed in my brain. I've corrected the actual function name above. The bleed was for a proprietary project I had active in my noggin when I was reading the question.
Related
Is there a way that I can run a piece of code before a session is created. In this situation, I would like to determine whether or not a session has been created for this user or not, and if not do something, and if so, do something else.
//Sudo code.
if(session.exists){
doSomething();
}elseP
createSession();
fillSessionWithValuesOnlyOnCreation();
otherLogic();
}
The thing is, Sessions seem to be created before I can make the check to see if the session exists, I've thought aabout checking the creation time and comparing it to current time, but I was curious if there is a better and more reliable way of doing it. I'm aware of a listener that can be triggered on session creation, but I'm not sure if it will have the request info I 'll need to populate the Session. And also not sure the order of executions, and if that listener will be triggered before filters execute.
I have a table in MSSQL database, and I have an ASPX page, I need to push all new rows to the page in a descending order. I found this awesome tutorial which is using SignalR and SqlDependency and it shows only the last row descarding the previous rows which have been added when I'm online, it does that because it has a span element to show data and every time it overwrites this span, so I modified the JavaScript code to append the new data and it works fine.
The problem now is when I refreshed the page for the first time, I'll get the new rows twice, and if I refreshed the page again I'll get the new rows triple .. and so on.
The only solution is to close the application and reopen it again, it looks like reset the IIS.
So, what can I do to avoid duplicating data in the online show?
It is not a SignalR issue, that happens because the mentioned tutorial has a series of mistakes, the most evident being the fact that it continuously creates SqlDependency instances but then it trashes them without never unsubscribing from the OnChange event. You should start by adding something like this:
SqlDependency dependency = sender as SqlDependency;
dependency.OnChange -= dependency_OnChange;
before calling SendNotifications inside your event handler. Check this for some inspiration.
UPDATE (previous answer not fully accurate but kept in place for context)
The main problem here is that this technique creates a sort of auto-regenerating infinite sequence of SqlDependencies from inside instances of Web Forms pages, which makes them unreachable as soon as you page has finished rendering. This means, once your page lifecycle is complete and the page is rendered, the chain of dependencies stays alive and keeps on working even if the page instance which created has finished its cycle. The event handler also keeps the page instance alive even if unreachable, causing a memory leak.
The only way you can control this is actually to generate these chains somewhere else, for example within a static type you can call passing some unique identifier (maybe a combination of page name and username? that depends on your logic). At the first call it will do what currently happens in your current code, but as soon as you do another call with the same parameters it will do nothing, hence the previously created chain will go on being the only one notifying, with no duplicate calls.
It's just a suggestion, there would be many possible solutions, but you need to understand the original problem and the fact that it is practically impossible to remove those chains of auto-regenerating dependencies if you don't find a way to keep track of them and create them only when necessary. I hope that part is clear.
PS: this behavior is very similar to what you get sometimes with event handlers getting leaked and keeping alive objects which should be killed, this is what fooled me with the previous answer. It is in a way a similar problem (leaked objects), but with a totally different cause. The tutorial you follow does not clarify that and brings you to this situation where phantom code keeps on executing and memory is lost.
I got it, although I don't like this way absolutely, I have declared a static member in the Global.asax file and in the Page_Load event I checked its value, if it was true don't run a new instance of SqlDependency, otherwise run it.
if (!Global.PageIsFired)
{
Global.PageIsFired = true;
SqlDependency.Stop(ConfigurationManager.ConnectionStrings["db"].ConnectionString);
SqlDependency.Start(ConfigurationManager.ConnectionStrings["db"].ConnectionString);
SendNotifications();
}
Dear #Wasp,
Your last update helped me a lot to understand the problem, so thank you so much for your time and prompt support.
Dear #dyatchenko,
Thanks a lot for your comments, it was very useful too.
In a web application, I need the SessionID for some reason, so, I save it in the database. the application does two redirects before it starts, and I found that it acquires two SessionIDs. The second one remains.
Why this behavior ? Any idea? How can I prevent that to save in the DB one record.
Sorry because I can't post code, it's compound with another logic.
There's a million possible reasons for losing / re-starting your session. Without your code, its difficult to offer advice.
One thing you can try on your own is to use the Session_End event in your global.asax file, as long as you're using inProc session. Put some code in there to have it tell you when the session ends, so you can track-down the problem / what's causing it to end in your application.
Another think you can look at is your method of redirecting. Make sure you're preserving the session, like this: Response.Redirect("~/default.aspx", false).
Another possibility is that you might not be putting anything into your first session. By default, you'll get a new sessionID on each postback unless you put something in the session.
I have a ASPX page which queries from a database. Once we have the dataset it is bound to a gridview and displayed on the page. All this happens in the Page_Load event.
Ofcourse this a simplistic approach. What is the best way to inform the user that data is being retrieved and when we have the data to update the page with the results in the dataset.
I want all this to happen within the same ASPX page and do not want to hop around pages to achieve this. I looked at update panels however it wasn't clear to me how this could be done with an update panel without having a control which triggers the update for the update panel. There are no controls on my page whhich initiate the database query, it occurs as the page is loaded.
If I do the query in a worker thread and then call the Update method on a UpdatePanel with the gridview as part of it, it doesn't work. Nothing happens.
Any thoughts or help? Thanks.
Well, this is a good question. Personally I have two pretty similar methods to do this:
Have a java script that will make an UpdatePanel reload with a short interval. This will create a series of post-backs to the server. During each post-back you should chek you worker thread and return immediately with the state report, usually one of error, pending, success + data
With a java script, make an asynchronous request to a web-service that will block until the data is fetched. This method brings no latency as compared to the previous one (the time between polls), but may suffer from some browsers/servers attitude to hanging open connections. This is normally solved by some interval (say, 1 minute) introduced, so that the hanging request will return with a message like need more time, in which case the java script should simply repeat the request.
My question is essentially the same as question 765054 on StackOverflow. I'm only asking it again because the accepted answer is incorrect (you can not access the session object in Application_BeginRequest).
Our use case is that we want to store the authenticated user's user object in the session. So in subsequent requests, we can correctly set the IPrincipal and IIdentity based on the user object in session.
Apparently AcquireRequestState is the earliest event where HttpContext.Current.Session is not null. I just attached to all of them in sequence and tested. I prefer to use PreRequestHandlerExecute which occurs before the constructor on my controller is called.
This is relevant if you would rather have your code in or referenced from the Global.asax instead. See this page for the sequential list of the events in the application lifecycle: http://msdn.microsoft.com/en-us/library/ms178473%28v=vs.100%29.aspx
I do similar things using a base controller and overriding OnActionExecuting. Whether this is the earliest it can be done or not, I don't know, but I do know that it will happen before your action is executed (and thus before the view is rendered). Alternatively you might want to have a custom authorize attribute that does what you want. This might be the only way to make sure that it's done prior to other attributes running.