Here's the question scenario:
Suppose you have a multiple-page ASP.NET web site with the following
requirements:
User-specific data for the currently logged in user is loaded and is required on each individual page of the application during a user's session.
The application itself only allows a certain number of users to be logged in at one time.
The next time a specific user logs in, the user should be returned to the last page visited.
Given this information, briefly describe how you would use ASP.NET to manage the state of the application to meet these needs?
Here's my thoughts and reasons. Please provide yours.
User-specific data for the currently
logged in user is loaded and is
required on each individual page of
the application during a user's
session.
This is suggesting to me that the interviewer is looking to see if I would suggest using Master pages as a way to provide a common approach to displaying the same thing on every page.
The application itself only allows a
certain number of users to be logged
in at one time.
Could the sought response be that, because scaling isn't an issue due to the limited number of users, that it is OK to put this information in the Session object for performance reasons or is this a trap and some of approach is better?
The next time a specific user logs in,
the user should be returned to the
last page visited
A cookie seems the best approach to track the last page access, since this doesn't seem to be critical information.
Please tell me how you would handle these question if you wanted to make the best impression
Feel free to provide input or comment an any line item.
Thanks!
As far as (3) is concerned, consider a shared PC. User A logs into a website using their site based user name/password. Does a whole load of work and shuts down the browser. USer B then comes along and on the same PC logs into the same site using their details. However, they will get the cookie from User A and be redirected to the last page they saw. This happens because Cookies are tied to the browser / OS user, where as you are potentially applying the site security separately in the application.
In this situation you would either need to put the user name into the cookie (encrypted) or use a server side method to store the location
Here are my thoughts:
They might be looking for Master Pages, but my first thought here was whether you're going to cache this user data, so you're not making a database query every time they hit a new page. To really impress them, you might mention partial caching techniques so that the repetitive portions of the page don't even need to be re-rendered with each page load.
I think you're right: they're helping you to conclude that the session state is an appropriate place to cache the user data. Just be sure you ask the appropriate questions, like "How many users?", and "How much data per user?"
The cached data could be used to keep track of the last-requested page, and when the user's session expires, you could save this data into a database table to be retrieved next time they log in.
That third item is awfully tricky. What if the user was last looking at an object that has since been deleted? What would be the intended behavior if a user logged in from one computer, did some work, and then logged in simultaneously from another computer or browser? I'd be sure to ask these kinds of questions, not least to show that I understand the implications of a requirement like this. If their responses lead you to believe that they're looking for a simple solution, go with the simple solution. Otherwise, tweak your response to be only as complicated as necessary.
Just a small thought.. If the system are running in a "Farmed" environment the Session data can be cleared and need to be handled some way.
http://www.beansoftware.com/ASP.NET-Tutorials/Store-Session-State-Server.aspx
Related
This question is not related to ASP.NET specifically, but more web applications in general.
I am building a web application wherein I am registering a user. As of now I am taking in very basic credentials like First Name, Last Name, etc of the user. In this website I am giving some information for free for any user who has just registered so that the user finds my website authentic and that it is not a fake website. After that, to get more information, the user has to pay.
The information my site provides will get obsolete after sometime. So, when a new user registers, he/she will get the new information that gets updated; but the old users have to pay to get the same new information.
My problem here is once the information gets obsolete the same person can re-register with a different set of credentials and get the new information. I want to avoid this from happening.
So my question here is this: what information should I request from the user, or extract from the user, to check that the same user is not re-registering? Or any other way to make this possible.
I am thinking of getting the IP address of the machine from which the person is registering and use it to check. But the user can use a different machine to re-register.
I am completely lost here and not getting the solution. I even checked on the Internet but could not find an answer.
Please let me know if you need any further information from my side.
You will not find a technical way to prevent users from registering multiple times. They can simply use another device, IP, another email account and different credentials.
What you can do is asking them to send you hard to fake "offline" information, like a credit card number or a photo of the ID. Some users may still be able to register multiple times this way, but probably not indefinitly. You will however lose many possible clients this way who are unwilling to provide such information for a test account, so this is likely not the solution you want.
My advice would be one of the following two:
Limit the information/service you give out to free users, so that even if they register again they will gain something when they pay.
Try to bind them to their account in a way where they would lose something if they threw it away. This may for example be providing user rewards for activity (real or virtual) or increasing their experience based on their history. Take SO for example: If you registered again, you would lose all your reputation. The users will think twice if this is worth the new content.
After reading all of the above, i think a good solution could be to let the user identify himself through facebook or linkedin. Few people will have a second account.
I think you cannot put any users like that because every thing can be duplicate
There are some ways for which the user must have payment mode or identity details like passport or it is windows application you can have finger scanner it will be definitely Unique..
You can do this (with limitations) with the use of cookies. Setting a cookie on the users device will allow you to determine who the visitor is and that they have already registered.
The limitations are that cookies can be deleted or blocked and are only valid for that specific user agent - the user could use a different device or a different browser on the same device. A lot of people don't really know about cookies though and how to delete them.
By tying this technique with a requirement to provide a valid email address you can make it a hassle for somebody to register more than once as they will have to create a new email account and then delete their cookies.
Whether this will stop enough people depends on your site and your requirements - if you're giving money away then this technique is not nearly good enough. If you just want to discourage the practice of multiple accounts it may be enough.
Your only way out is to have SOMETHING the existing user gets as a "gift?" or added value to maintain just one account. If you can identify items of value to your subscribers and offer to "give" it to them provided their account "attains" one or more status, then you'll get some control. Take stackoverflow.com for example, I don't need a second account.
Identifying by facebook or linkedin is a good option, but if you are giving such services. which are very beneficial for the users, so they dont mind on creating multiple accounts on even facebook or linked in.
So what i think is to set some reward type stuff with each user, and increase the services as they get increment in rewards.once they are good in rewards and are capable to use multiple services, this increases the probability that they will not create another account.
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.
My question is how to best handle temporary data for an session. The scenario is similar to a shopping cart or like a bet slip. While the user is navigating the site and adding items with unique ID's. I'm only interested in the data collected this way if the user wants to commit it.
I'm developing in ASP .Net 3.5 with jQuery,JSON and a MS SQL DB.
As I see it there are a few possible ways to do this.
Perform a full post back to the server. Store every selections, update page controls accordingly.
Send selections via a Ajax request back to the server and update displaying control.
Build all functionality in JavaScript and store all values in a session cookie. Nothing being sent to server until user choose to commit.
I really want to consider performance here but I don't want to end up with 1000's of lines of JavaScript code..
Any suggestions of the best implementation with pro's and con's?
Cheers,
Stefan
Storing things in a session cookie is not a good idea, because that will be sent back to the server with every request. If you could find a way to store the state on the client without using a cookie, then you might have a viable client-centric option, but i can't think of anything portable off the top of my head. There are things in HTML5 and Flash that can do it, but you don't want to go there - yet, in the case of the former, and at all, in the case of the latter.
I'd use AJAX to post back to the server (with graceful degradation to a full post for browsers that can't handle that), then store the information in volatile memory there - ie not in the database. Write it to the database only when you need to. This is very easy to do in Java (you can associate information with the session), so i assume ASP.net has some way to do it too.
All three possibilities look good to me. The question, however, is: how much traffic do you expect?
Each of the options you presented suits better to a given scenario. Let's say you will have A LOT (thousand of thousands) users and not a lot of hardware available then you should probably try to minimize the number of requests to your app and store data in the client as much as possible before sending it to the server.
If it is smaller application then using Session or some other central database storage would be fine.
It all depends on your requirements.
I am facing an issue when we are using multiple tabs since its sharing the same session. Any alternatives to this? Can we create a unique session when someone uses the tab or CTRL+N.
It's a Java EE/Struts2 enterprise application if this matters.
This is a problem all server-centric web applications face, it's not specific to Java EE. The problem is that most browsers store cookies on a per-user basis, not per tab. Also, this behaviour is not generally transparent to the user, adding to the confusion. A few solutions I can think of (although none of them is really satisfactory):
Host the application under more than one URI. This way, any browser will store cookies independently, and consequently, you have one session per application version.
Propagate session IDs through a different mechanism, e.g. through the URI. This, however, has a few caveats - it exposes the session ID to the user, it makes for ugly URIs, and it forms a security risk (session hijacking and such) when users copy-paste or bookmark the current URI (because they then store the session ID in the link).
Propagate session IDs through hidden fields inside the page. This solution probably requires you to rewrite part of the built-in session handling, and it loses the session ID when your page contains links to other pages within your application.
For Firefox, there's an add-on called "cookie pie", which allows users to have independent cookie stores for some or all tabs. Downside is that users have to actively enable it, and working around the tab problem becomes the user's responsibility. Also, it doesn't work under all circumstances (e.g., google finds your active login regardless).
Avoid using session state, and use other mechanisms to preserve state between requests. Like passing session IDs through hidden fields, this breaks under certain circumstances.
Make the application fully client-centric, that is, program the entire interface in javascript and communicate with the server through ajax calls. This way, you won't depend on the browser's cookie implementation at all. Chances are you'll have to rewrite substantial amounts of code though, assuming your application is basically working already.
There is no simple way to achieve this that I know of.
The usual way to fix this is to change the app so that it can deal with users using multiple tabs (if possible).
There are several workaround ideas for how to "disable" the old window if the user presses Ctrl+N while walking through a multi-step form, but you'd have to give more detailed information for ideas on that.
Usually a browser instance is treated as a single user/entity for session tracking purposes. Especially if you are using cookies to track the sessions. I am not sure that I like the idea of allowing different tabs to have different sessions. It feels unintuitive for web based applications. All IMHO, of course.
That said, if you want to change this you will have to come up with a custom implementation. Perhaps you can generate and attach different session ids to the URL for different tabs. Never tried this myself so do not know how easy or difficult it will be.
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.).