Session State from Single instance to Multi Instance - asp.net

In my current assignment - I have to implement a solution for the session state management issue. The current implementation is as follows:
There is a asp.net form that allows you to add multiple entries to form a batch.
The fields represent a single entry (most of the fields are auto complete) - once you fill all the fields and click the 'add' button - the entry gets added to a grid view - Each time the 'Add' button is clicked it causes a post back and the grid view repopulates displaying the previous entries.
After repeating the above steps multiple times to enter multiple entries - all are displayed in the grid view - you then click the 'Enter Batch' button - that submits all the entries in the grid view as a batch to the database.
The issue: To enable most of the above functionality - there is session state (InProc) implemented all over the page and other pages as well. The problem is - Users can open multiple instances of the same application, and then the application goes crazy. The other issue being - at times the application kick off the users and they have to re log in and when the do that all the entries they where doing in the batch are gone from the gird view.
I see session implemented everywhere on the web form. The most obvious solution to resolve the above two issues - is to implement a Session State (SQL Server) mode.
But before I move ahead with the implementation I have couple of questions, If anybody can help:
1 Can I change the current implementation (so that I don't have to re write the session variables already used on the web form - as they are two many) - I tried to change the web.config to have the (sessionstate cookieless="true" - I was hoping this would put the session ids in the URL, in turn enabling session state of multiple instances) - however after doing that - the auto complete feature on most of the fields don't work, so I have change the config to allow cookies based. So is there a way to change the current session implementation to make it work properly around multiple instance of the application.
If I have to implement session state afresh - can someone give me a brief overview of how to implement the Session State (SQL server mode) so that it works around multiple instances - like what to use for unique key (how to set and get session variables base on this key for multiple instances) and how to configure the tables in database etc.
Note: the current session state is 'InProc' mode and I can say that cause there it is not set anywhere so I think that's the default. The session variables are pretty standard in the current implementation.
This is a new project I have started - and this is my first assignment - however the code is really messed up - it dose not have a modular or even the basic 3 tier implementation. The code is very unmanageable and hard to debug.
Any help and suggestions are much appreciated. Thank you guys.

All that is required is given at Session-State Modes.
Your code for storing/retrieving session state does not change.
Is State Server Mode out of the question?

Related

Lock page / entity edits if another user is editing

I have an asp.net page to edit an entity. What is the best design pattern to notify and prevent saving when another user is already on the edit page for that entity. I would want the lock to expire when the user leaves the page. I would also like to display the user name that has the page locked.
Session state could be either inproc or state server.
The user needs to know before attempting to save (for example disable the save button for all other users on the edit page)
There are many different ways to do this, but in general it is fairly complex. One challenge to be aware of is that you don't know when a user leaves a page as there is no way to signal that.
One approach that I've seen used a few times is to do the following:
Add a column to identify who has the record locked (e.g. add Locked_User_ID etc to your table)
Add a column to identify what date/time the record was locked. (e.g. Locked_Timestamp)
Define a global constant (config setting, etc) specifying how long a lock is good for.
On page/controller load, check to see if the record in question is locked, and if so, was it locked recent enough (based on your global constant) to believe that another user is still working on it. If so, don't allow editing and display the user that is editing and their last activity (based on Locked_Timestamp & Locked_User_ID).
If it was not locked recently enough, or is not locked at all, or is locked by you, update the Locked_User_ID to the current user and Locked_Timestamp to the current date.
Once the user clicks back/cancel, save, etc, unlock the record. (that way it doesn't have to wait for the timeout based on the global constant - but in the event they just close the browser, etc the timeout will be the failsafe).
Another slight variation of this to have a "check-out" or "edit" button/functionality that implements this - so that users can view information without automatically acquiring a lock on it, and only once they click "check-out" or "edit" does it check and acquire the lock.
Hope this helps!
Regards,
Ross

I have multiple users, can i lock the web page so that only one user at a time can update a record?

Can anyone help or provide me with some suggestions for the below query.
I have a web form (Minutes of Meeting) and 8 users that need to access this web page and update their area. A user may have more than one area to update and essentially i would like to some how lock down the web page if possible when a user is using it so that no other user can update this web page till joe bloggs has finished with it.
I have a Active Directory security group set up to restrict the site to that group of users only, but i need to think of a solution to the above?
Is there a way i can do this via a web control or via SQL?
There must be better ways to do it. However, Is it possible for you to introduce a sql table column similar to "UpdateInProgress" (bit). Any update process sees that column, If 0 then It updates to 1 and after It saves the changes and updates back to 0 so that the form is available for other to update. If update process sees 1, It can't update the web form because update is in progress.
I also suggest to introduce another column named "UpdateInProgressBy" to check who has opened it for editing.
First of all we must note that there is a big time from the moment the user reads the data, get it in a page, change them and then try to write them back. So we are not talking for the lock command on SQL, nether any other lock that happens in milliseconds and help to synchronize threads, but here we must synchronize people and what they write.
There is also a problem if the user leave the page for any reason and this can make the data lock for ever.
This problem can solve with two approaches.
the easy one, when a user try to save data you must check if the same data have been change in the middle, and warn him, or show a merge dialog, or merge programmaticall, or something similar - I do not know what you won.
the difficult way is to constantly monitor the page that read and change the data, and keep this monitor results on a common table in the data base, and there if a user have been and stay on page, the rest users get a warning and read only data, until the user go.
This monitor must be made with javasript and must know even if a user abandon the page.
SET TRANSACTION ISOLATION LEVEL as SERIALIZABLE
for more information check this link:
http://msdn.microsoft.com/en-us/library/ms173763.aspx

Replacing ASP.Net's session entirely

ASP.Net session appear perfect for a traditional WebForms app, but they do some things that are a serious problem for a modern AJAX and MVC application.
Specifically there are only 3 ways to access the ASP.Net provider:
Locking read & write (default) - the session is locked from AcquireRequestState firing until ReleaseRequestState fires. If 3 requests occur from the browser at once they'll queue up on the server. This is the only option in MVC 2, but MVC 3 allows...
Non-locking read only - the session isn't locked, but can't be saved to. This appears to be unreliable though, as some reads appear to lock the session again.
Session disabled - any attempt to read or write to the session throws an exception.
However with a modern MVC app I have lots of AJAX events happening at once - I don't want them the queue on the server but I do want them to be able to write to the session.
What I want is a fourth mode: Dirty read, last write wins
I think (happy to be corrected) that the only way to do this is to completely replace ASP.Net's sessions. I can write my own provider, but ASP will still call it with one of the 3 patters it supports. Is there any way to make ASP.Net support optimistic concurrency?
This leaves me replacing all calls to the session with a new class that basically does the same thing, but doesn't lock - which is a pain.
I want to keep as much of the current session stuff as I can (most significantly session IDs in various logs) with the minimum amount of code replacement. Is there any way to do this? Ideally I'd want HttpContext.Current.Session to point to my new class but without ASP.Net locking any requests.
Has anyone already done something like this? It seems odd that with all the AJAXey MVC apps out there this is a new problem with ASP.
First of all I say that MS asp.net have lock in the core of "asp.net processing a page" the session, somewhere in the "webengine4.dll" dll for asp.net 4
And I say that from the view point of MS asp.net act correct and lock the session this way because asp.net can not know what type of information we keep on session so can make a correct "last write wins".
Also correct is lock for the session the full page because that way is gives your a very important synchronizations of your program, that from experience now I say you need it for most of your actions. After I have replace the ms session with mine, on all of my actions I need to make global lock, or else I have problems with double inserts, double actions, etc.
I give an example of the issue that I recognize here. Session data are saved on SessionSateItemCollection that is a list of keys. When session reads or write this collection is do it all of them together. So let see this case.
we have tree variables on session, "VAR1", "VAR2", "VAR3"
Page 1.
getsession (actually get all data and place them on list)
session[VAR1] = "data1";
savesession()
result is VAR1=data1, VAR2=(last data of var2), VAR3=(last data of var3)
Page 2.
getsession (actually get all data and place them on list)
session[VAR2] = "data2";
savesession()
result is VAR1=(last data of var1), VAR2=data2, VAR3=(last data of var3)
Page 3.
getsession (actually get all data and place them on list)
session[VAR3] = "data3";
savesession()
result is VAR1=(last data of var1), VAR2=(last data of var2) VAR3="data3"
Note here that each page have a clone of the data, as he read them from the session medium (eg as they last readed from database)
If we let this 3 pages run with out locking, we do not have actually dirty read, nether "last write wins" - What we have here is "the last write destroy the others", because if you think it again, when VAR1 change, why the VAR2 and VAR3 stay the same ? what if you have change VAR2 somewhere else.
and for that reason we can not let this with out lock as it is.
And now imaging that with 20 variables... totally mess.
Possible solutions
Because of the multithread of asp.net of many pools, the only way to keep the same data across pools, and across computers is to have a common database, or a common to all process program like the asp.net State Service.
I select to have a common database as more easy than create a program for that propose.
Now if we connect a cookie that we make, to the user to the data user of the session, and we control the data using a totally custom database field that we know what we like to lock, what not, how to save or change, or compare and keep the last write wins data, we can make this work, and totally disable the asp.net session that is a generic session keeper made for all needs, but not made to handle special cases like this one.
Can asp.net make this work on the future release, yes he can by making an extra field called dirty, and on the session save data, make a merge of data using the dirty field, or something like that, but can not make this now work as it is - at least from what I have found until now.
Actually SessionStateItem have a dirty flag on properties, but did not make this merge on the end of save data. I will really love if some one else think for a solution to the existing ms asp.net session state keeper, I am write what I have found up to now, but this is not mean that for sure there is no way - I have not found it as it is.
Hope that all helps :)
Custom SessionStateModule
in this answer https://stackoverflow.com/a/3660837/159270 the James after write a custom module says: I still can't believe the custom implementation of ASP.Net Session locks the session for the whole request.

Navigate Page to Page in Web Application Keeping user inputs

Is it possible in an ASP.NET application to keep what the user has entered from one page to another, similar to a Windows Application? so when the user navigates back to the main page, all the info entered still remains.
I can think of a couple of options (there are probably more):
Cookies.
Individual Session objects for the data you want to persist
Single Dictionary object stored in session that holds the question/answer pairs.
Round trip to the database each time and retrieve/store the answers based on some key.
I would personally choose option 3 (combined with saving to the DB when appropriate). The dictionary object is easy to work with and you limit the amount of useless crap floating around in Session and cluttering things up.
It really depends on your specific application, though. Some more details would be helpful.
I think sessions are ideal here...

access forms as asp.net's listview

I made an access vba application where all my architecting was simply creating a one-to-many relationship between a "status" table and a "data" table that contained all the other details of my record. Created a form with the single click of a button with my "status" table open, and wallah,,, I got a form for my open or closed records that had dropdowns for each field where theres a related table. For activity tracking, I had to make a many-to-many table , and made a one-to-many for the status of those activities and again, clicked the create form and I was in business. To finish things off all I did was integrate a checkbox in my data fields and put buttons on my status forms that act on the record that got checked, and I was done, fast & painlessly, kinda.
Is there any ASP.net code generation of a data control in where I can just structure my MYSQL database, make the relationship and generate code of the RELATED "status" table and get my form w its related subform with text fields & DDL's automatically generated, fast? If not, what would you consider is the next best approach (i.e. using excel for replicating repetitive code)?
Take a look at http://www.asp.net/dynamicdata
As far as I know (having not used it myself) it will do what you need, ie quickly generating data entry pages from an existing sql schema.
Access can actually create .net forms when you use access 2010. (the forms are real xaml or so called zammel forms). The beauty of this system is you get to keep the same point and click approach that allows you to build master forms with child sub-forms. You not have to write one line of code and you not ever see one connection string. Only downside of this great new system called "Access Web Services" is it requires SharePoint (enterprise).
So, this is a true access development for the web, but you continue to use the Access client to build those forms. Those forms scale out to many users since you using xaml forms and SharePoint. Here is a video of this in action:
http://www.youtube.com/watch?v=AU4mH0jPntI
At the half way in above, note how I switch to running the access application 100% in the browser.

Resources