ASP.NET - Prevent duplicate DB transaction on refresh - Multiple Tabs - asp.net

I have multiple ASP.NET Gridviews on a page, and each has their own Insert/Update/Delete commands.
In order to prevent duplicate DB transactions on page refresh, I am using a Session variable similar to this method here: Example (src: http://aspalliance.com/articleViewer.aspx?aId=687&pId=4)
That works as intended. The problem is that many of our users have multiple tabs open performing actions on different search criteria. If a user runs a transaction on one tab, then switches to another tab, the next transaction they attempt will not commit at all. Since the Session variable has now updated from the other tab, it will prevent the transaction thinking it's a page refresh.
I also cannot redirect to the same URL, as I would lose all search criteria and other form values that need to persist on postback.
Any other tips to have an ASP.NET site running in multiple tabs and also preventing duplicate DB transactions?

Related

asp.net refresh web page on DB changes

I'm currently working on an asp.net website.
I have a page (main.aspx) which displays records from a database table. Another page (editing.aspx) is responsible for editing records in the DB table.
let's assume we have a scenario where two users are using the website, user1 (on session1) is viewing the records in main.aspx, user2 (on session2) is editing the DB table from editing.aspx, what I want is: to refresh main.aspx for user1 when user2 saves his changes to the DB table.
I tried using an AJAX timer that pulls the DB for changes every 10 seconds, and refreshes an UpdatePanel (in which I'm displaying the records), and it works just fine, but I want to know if there'se a better way than pulling the DB server for changes.
thanks.
It is debatable if the other way is better but what you are looking for is persistent connection to the server that lets the server send e message to the page. There is a good library for .NET called SignalR that abstracts away the details. It is certainly more network efficient but depending on your use case the update panel may be good enough. Basically with SignalR you will send a message from the server-side code of your edit page which would be received by a JavaScript function on your main page. Then you either show the data or cause a refresh in some way.

is sql transaction can apply in web application

Can I use sql transactions in web applications?
I.e. when a user starts filling forms the transaction begins. But when another user fills the form at the same time does he get another transaction?
The form is complete when three pages of data are submitted by the user. The data are saved to different tables after filling the specific pages; after completing all form pages the commit should be invoked.
Does this work for a web application where there may be multiple users at same time filling in forms?
I used this method but I get errors that the database/server is not responding/busy.
Is there is any other option to avoid incomplete form submission?
Using a transaction on a forum application is not going to be a good idea, if 2 users are trying to submit new threads at around the same, User 2 would be blocked from accessing/updating tables with the data they are submitting until User 1's transaction is committed.

ASP.NET: How to limit access to a page to just one user?

How to restrict the page by accessing only one user at a time. Using asp.net can i use global.asax, is there any other way to restrict, if one user accessing the page, another user not able to access that page. we have to give message that one user is accessing the page. is it possible. can you help me or give some reference.
Although there are probably many better ways of dealing with this sort of problem, I'm going to assume that you do actually need this.
What I would do:
Make your application so that when the page is loaded(when it isn't "locked"), it logs to a database that the page was loaded and "lock" it. In the actual page, I'd have some kind of AJAX to constantly poll the web server every 5-15 seconds to tell your application the user is still on the page. And then make it so that the page becomes unlocked after 5-15 seconds from the time saved to the database by the last AJAX call.
Again, I really suspect that there is a better way around an issue like this, but this is a direct answer to your question
Based on this:
yeah sure, jupaol, it is depend on accounts, in my web application, one report has to approve only one user, but the approve authority having two users. if both of them accessing the same page and approve at a time, it will big mess. here i an not using database.
The problem is related with concurrency, there are several ways to face an issue like this, for example the easiest one is to use optimistic concurrency. Even when you are not using a database for this, you can emulate it.
You should be storing the result of the approvers somewhere, in order to mark the report as approved, with this in mind you should be able to do something like this:
Before render the page get the latest report status
If the report has not been approved, render normally
If the report was approved seconds before, render it in read-only mode reporting who approved it (or similar approach)
Add a validation to your ChangeStatus method, in this method do the following:
Get the latest status of the current report
If the report is still not validated, then block the thread (you could use a Mutex or similar) and mark the report as validate it
If the report was already validate it, raise a domain exception and handle it in your page correctly (perhaps render the page in read-only mode explaining that the report was already validate it)
If you want a more responsive application, (RIA), you might want to consider the following approaches:
Perhaps this would be the worst approach but it's still an option, you could keep a log tracking when a user request your page, then in subsequent requests check if the log is still valid, if it is not, then redirect to another page indicating the page is in use, otherwise allow access to the page. I believe this is an error-prone approach because you would be relying on this simple validation in order to prevent an inconsistency in your system, besides you would have the polling problem described in the following approach
Using AJAX to poll data from a service checking if the report has been approved. Perhaps this is the easiest way to accomplish this but it is not recommended it, because you would be polling your server constantly, and eventually you would have scalability problems
You could use Comet to get notified to the browser (client) whenever a server event has occurred, in this case when your report has been approved. The problem with this approach is that you have to keep an opened connection with the server in order to get notified.
The last approach and the most recommended these days is to use Web Sockets, this is the technology used in StackOverflow to get notifications in real time.

ASP.NET State Management in appropriate situations

There are 6 techniques to manage states in ASP.NET 3.5 (as far as I know).
(1) View State
(2) Cross Page Posting
(3) Query String
(4) Session State
(5) Application State
(6) Cookies
Can anyone give me some appropriate examples of situations where I should use these techniques?
For example:
(*) Session State: Personalization, Buy Cart, etc.
(*) Cookies: Saving User Credentials, etc.
There's a lot of factors that can influence this, so I won't comment on all of them. But here are a few pointers:
ViewState - This is useful when you'll be posting back to the same page frequently (something you're practically forced into doing by ASP.Net Webforms). How useful it is exactly changes depending on what kind of app you're building. For public internet sites, it should be used very sparingly. You may even want to turn it off by default. For local intranet sites, it's a great tool — especially for the fewer, heavier, webforms pages.
Query String - Use this to store state that you need to allow the user to bookmark a page or process and come back to much later. Even then, you might want to keep it down to some kind of hash that you can use as a key in a database lookup to avoid a really huge url (though hashes have their own problems). Also, a lot of users like to fiddle with your query string directly, so it can be dangerous to put too much here. It's easy to accidentally expose data to users who aren't supposed to see it this way.
Application State - Remember that this is shared by all users, so use appropriately. Things like view counts can go here.
Cookies - Don't use cookies to store user credentials. They're just plain unencrypted text files. Use cookies to store a key into the session (even here you can and should now use cookie-less sessions) and simple personalization settings that will be specific to that user and browser. For example, my monitor size at work is different from home, and so putting display size/layout settings into a cookie is nice because the settings stick for each computer, but it isn't going to compromise my security any if someone else reads that information.
Now I want to highlight this concept from the "Query String" section:
you might want to keep it down to some kind of hash that you can use as a key in a database lookup
Again, hashes have their own problems, but I want to point out that several items on my list talk (including Query String) about uploading data from the client web browser to the web server: ViewState, Query String, Cookie, and Cross-Page Post. You want to minimize the data that you move from client to server. This concept applies to all of these, and for several reasons:
Pulling data from the client is slow for public internet sites. Even broadband connections typically cripple the bandwidth available for upload. 512Kpbs (still a typical broadband upload rate in many areas) is nothing when compared to the Gigabit Ethernet (or faster) connection that likely sits between your database and your web server. As much as you might think of a database query as slow (and it is), it's still likely a much better way to go than waiting for the same data to arrive from the client.
Keeping the data on the server is cheaper, because you don't pay for the bandwidth required to push it to or from the client, and bandwidth often costs as much or more than your server hardware.
It's more secure, because if done right even when a client's computer or connection is compromised all the hacker has access to initially is a hash key that likely expires by the time he can decrypt it. Of course, if done wrong he can use that key directly immediately, so you still need to be careful.
So for most things, what I recommend is to start out by keeping a database key in the Session and then have code to easily pull what you need from a database based on that key. As you experience bottlenecks, profile to find out where they are and start caching those pages or controls, or keep that data/query result in the session directly.
State management option
View state:
Use when you need to store small amounts of information for a page that will post back to itself. Using the ViewState property provides functionality with basic security.
Control state:
Use when you need to store small amounts of state information for a control between round trips to the server.
Hidden fields:
Use when you need to store small amounts of information for a page that will post back to itself or to another page, and when security is not an issue.
You can use a hidden field only on pages that are submitted to the server.
Cookies:
Use when you need to store small amounts of information on the client and security is not an issue.
Query string:
Use when you are transferring small amounts of information from one page to another and security is not an issue.
You can use query strings only if you are requesting the same page, or another page via a link.
Server Side Management Options
Application state
Use when you are storing infrequently changed, global information that is used by many users, and security is not an issue. Do not store large quantities of information in application state.
Session state
Use when you are storing short-lived information that is specific to an individual session and security is an issue. Do not store large quantities of information in session state. Be aware that a session-state object will be created and maintained for the lifetime of every session in your application. In applications hosting many users, this can occupy significant server resources and affect scalability.
Profile properties
Use when you are storing user-specific information that needs to be persisted after the user session is expired and needs to be retrieved again on subsequent visits to your application.
Database support
Use when you are storing large amounts of information, managing transactions, or the information must survive application and session restarts. Data mining is a concern, and security is an issue.
Not sure if you mean the Cache object by Application State.
The Cache object is a great way to manage application wide state, e.g. to record source and count access to your website (to prevent DDOS attacks for example).
(3) Query String
(4) Session State
(5) Application State
(6) Cookies
1. Viewstate
Disclaimer: Use as little as possible. Good point is to always have each state reachable by an url, if possible.
F.e. Paging should use the URL (so /url/?p=2 instead of storing the page in Viewstate)
Use to persist control state between page-cycles.
F.e. Store the selected item in a checkbox, so you can determine whether it has changed.
2. Cross Page Posting
Don't. See the disclaimer for viewstate. Use the URL for this, or store the data in a session / cookie / profile if loads of properties need to be kept around.
Major downside of CPP is that the user cannot use the 'Back' and 'Forward' buttons in it's webbrowser. When a user clicks the back button it wants to undo everything on that page and retry the last one. When using CPP to click them through a wizard; this behavior is not possible without a lot of 'Are you sure you want to resend blablablabl'.
3. Query String
Use alot. Every visible state that a page could reach should be accessible by URL. People with screenreaders will thank you for this. And by using the query string there is no need to use javascript-only solutions.
/url/?page=2 // when doing paging, don't use postback for this
/url/?tab=advanced-search // when having tabs on top of your page
etc.
4. Session state
Use this for short-living objects, that only make sense this time the visitor visits your site. For example:
Which step of a certain wizard was reached
Pages a user had visited before
Small objects you want to put in cache, but that are user-bound
Don't use sessions but profiles for things like:
Preferences
Selected language
Because those things also make sense the next time the user visits your site.
5. Application state
Never. Use ASP.NET cache, or memcached, or any caching framework for this.
6. Cookies
Session ID, Profile ID for authenticated users; user preferences for anonymous users (everything listed in the second list under 4.).

How much data can/should you store in a users session object?

We have several wizard style form applications on our website where we capture information from the user on each page and then submit to a backend process using a web service.
Unfortunately we can't submit the information in chunks during each form submission so we have to store it the users session until the end of the process and submit it all at the same time.
Is the amount of server memory/sql server disk space the only constraint on how much I can store in users sessions or is there something else I need to consider?
Edit: The site is built on ASP.NET web forms.
Assuming the information is not sensitive then you could store the information in a cookie which would reduce the amount of information required to be stored server side. This would also allow you to access the information via JavaScript.
Alternatively you could use the viewstate to store the information although this can lead to large amounts of data being sent between the server and the client and not my preferred solution.
The amount of session information you should store varies wildly depending on the application, number of expected users, server specification etc. To give a more accurate answer would require more information :)
Finally, assuming that the information collected throughout the process is not required from page to page then you could store all the information in a database table and only store the records unique id in the session. As each page is submitted the db record is updated and then on the final page all the information is retrieved and submitted. This is not an idea solution if you need to retrieve previous information on each subsequent page due to the number of db reads required.
You could also have 1 asp page with the entire html form, and hide parts of it until the user fill and "submits" the visible part...
then simply hide the part that is filled out and show the next part of the form...
This would be extremely easy in the .NET framework, use panels for each "wizard step" and add loggic when to display and hide each panel.
you will then have all the data on one page.
If you use a traditional HTTP model (i.e. don't use runat="server") you can post the data to another asp page and place the posted data into hidden form elements, you can do this for however many pages you need thus avoiding placing anything in a session variable.
Since it is problematic from performance point of view to store large amounts of data in user Session object, ASP.Net provides some other workarounds on top of what is mentioned in the posts above. ASP.NET Profile Provider allows you to persist session related information in a database. You can also use Session State Server which uses a separate server to store all Session information. Both of these situations take into account if you need to use clusters or load balancers, the servers can still recognize the session information across different servers. If you store information in the Http Session object, you run into the problem that one user must always go to the same server for that session.
Session, viewstate, database. These are all slow but will get the job done.
Hidden form fields is the answer I like best.
There are other ways to persist state. Cookies, popup window, frameset or iframes.

Resources