ASP.NET Cross Page Posting via HttpRequest || Page.PreviousPage? - asp.net

I've been developing classic ASP pages at the job for the past five years and now we are moving to ASP.NET. I'm trying to understand how to get form field values from one page to another and it seems like there is more than one way to do it. In classic ASPI just called request.form collection and got the information. Which way is recommended in .net? Cross Page, Transfer, or HttpRequest?
Gracias.

It actually depends because I don't always use any particular method. Sometime it is easy to expose as property or sometimes just server.tranfer is fine or sometimes as querystring.
If data is sensitive and/or to many itmes I use Session where you can store an class object of custom type as well and not just basic data type.
And in certain cases I store stuff in DB and just pass an id to the record to next page via querystring or session and retrieve everything I want from DB.
Here is reference to different types available.

Related

Using ViewState variables

I want to use viewstate variable's value which is saved in one page on another page. But while doing so it shows NullReferenceException. I am new to ASP.net. Please Help me out.
in register.aspx
ViewState("name")=textbox1.text
in success.aspx
dim a as string
a=ViewState("name").toString
Use Session["name"] = textbox1.text...
If I am not mistaken, you don't have direct control or should have direct control over viewstate.
ViewState is the technique to persist state across postbacks and is lost when you load another page. therefore you will need to use another way to send the data to the next page. Read up more here on MSDN
The common choices for sending data across pages include:
QueryString
By setting up the previous page property
Session variables
ViewState is restricted to a page, so it cannot be used on another page. The reason is that ViewState is serialized in the page output in a hidden field that is transferred to the client and back to the server upon a postback.
If you want to transfer data to another pages you have several other alternatives:
As #AnastacioGianareas also pointed out, Session memory is one of them. It is located on the server, but sessions will expire after a certain time of user inactivity. Being located on the server, it reduces application scalability if you have many users and lots of memory allocated in the session.
Hand over the data as a query string parameter to the other page, e.g. redirecting to "Success.aspx?name=". This will work for smaller amounts of data that you can put into the query string (e.g. ids or names). It is important that a client can also request Success.aspx with that query string parameter, so it should be reserved for uncritical data and be validated carefully.
Use a cookie to transfer it to the client and back again.
This link gives a good overview of the alternatives.
From MSDN:
View state is the method that the ASP.NET page framework uses by
default to preserve page and control values between round trips. When
the HTML for the page is rendered, the current state of the page and
values that need to be retained during postback are serialized into
base64-encoded strings and output in the view state hidden field or
fields.
Options to persist data between pages are varied and depend upon your requirements, this page on MSDN describes each of these options and the considerations you should make.
For your requirement either QueryStrings, SessionState seem like the best solution.
As a side note, always validate your 'State' variables (regardless of which method you chose) to ensure that they aren't null and are of the expected type. i.e. all these values will be stored as Strings, if you are going to use a variable as another type (an int, double etc) you should make sure this is valid. Also, should you go down the querystring route, take into account any security considerations as users may / will modify these values.

session object design pattern

I'm looking to build an ajax page; it's a reporting page. By default, load today's report. On the page there's a calendar control and when the user clicks on a date, reload the gridview with the corresponding data. Is it considered good practice to do the following:
1) on the first page load, query the data for the page
2) put the query result in the session object and display it in a gridview
3) if the user requests new data, get new data from the query with different parameters
4) put the result of the second query in the session object and display it
5) if the user then requests the data from the first query, get it from the session object
6) do the sorting and paging with the data held in the session.
Note: the data of each query will contain about 300-500 rows and about 15 columns. I'd like to do all this with ajax calls. What are some suggestions and pitfalls to avoid.
Thanks.
I would use Backbone.js:
Server produces report in JSON format.
Client has a Backbone.js Model for this report, which binds to the JSON endpoint.
Client renders the Report Model as a Backbone view.
Client reloads the report from server only when appropriate.
Reports from previously viewed days will still be around in the client as Backbone Model instances, so you don't need to reload from server unless the user forces. I believe this is your main concern?
You're probably still in the realm of can-do-without-a-client-side-framework, but if you plan on doing more of these pages or getting any more complex, you can go to spaghetti pretty quickly without something like Backbone.js.
PS. I just noticed this is .NET related. I know nothing about .NET so maybe there's a built-in client-side framework that can do something similar.
EDIT (updated after reading comment):
For server-side caching, I think a either a denormalized report table in the DB or a separate dedicated cache store (e.g. memcache) is a better practice than session object.
It depends though. If there was say, 1 possible report per-user per-day, and you didn't have memcache set up, and you don't want to use the DB for whatever reason, then it could make sense to store it in their session object. However, if each day's report is the same for all users, you're now caching it N times instead of 1. It could also be hard to invalidate from an external hook and the user loses their cache when they logout.
So I would probably just have a typical get-or-set pattern to try and load report from cache first, and fallback to DB. Then invalidate/update the cached report only when the user forces, or if data used to create the report has changed. AJAX call requests the report by date or however a report is identified.
Since you are hoping to use the data in Javascript Ajax scenerios it would make the most sense to create a HTTP Handler to query and return the needed data result sets on demand.
Using the session object is not a solution because it cannot be accessed asynchronously. As a result, your page would not be able to query this data to feed back to your Javascript objects (unless you created an HTTP Handler to send it back, but that would be pointless when you could just query the data in the HTTP Handler directly).
You are forgetting about windows. A client isn't a window, a client is a browser it can contain many windows/tabs. You need to make sure you are rendering/feeding the correct window. Usually i handle this by submit hidden values.
Problem is separating resuming a session / Starting a new window.
I wouldn't bother holding more than one copy of the query in the Session. The primary reason you'd want to hold it in Session is to improve the sorting/paging speed, presumably. Users expect those to be relatively fast, but choosing new dates can be slower. Plus, what's the likelihood that they'll really reload the first query?
The other answers raise good pitfalls with storing in Session in general.

Why are hidden fields used?

I have always seen a lot of hidden fields used in web applications. I have worked with code which is written to use a lot of hidden fields and the data values from the visible fields sent back and forth to them. Though I fail to understand why the hidden fields are used. I can almost always think of ways to resolve the same problem without the use of hidden fields. How do hidden fields help in design?
Can anyone tell me what exactly is the advantage that hidden fields provide? Why are hidden fields used?
Hidden fields is just the easiest way, that is why they are used quite a bit.
Alternatives:
storing data in a session server-side (with sessionid cookie)
storing data in a transaction server-side (with transaction id as the single hidden field)
using URL path instead of hidden field query parameters where applicable
Main concerns:
the value of the hidden field cannot be trusted to not be tampered with from page to page (as opposed to server-side storage)
big data needs to be posted every time, could be a problem, and is not possible for some data (for example uploaded images)
Main advantages:
no sticky sessions that spill between pages and multiple browser windows
no server-side cleanup necessary (for expired data)
accessible to client-side scripts
Suppose you want to edit an object. Now it's helpful to put the ID into a hidden field. Of course, you must never rely on that value (i.e. make sure the user has appropriate rights upon insert/update).
Still, this is a very convenient solution. Showing the ID in a visible field (e.g. read-only text box) is possible, but irritating to the user.
Storing the ID in a session / cookie is prohibitive, because it disallows multiple opened edit windows at the same time and imposes lifetime restrictions (session timeout leads to a broken edit operation, very annoying).
Using the URL is possible, but breaks design rules, i.e. use POST when modifying data. Also, since it is visible to the user it creates uglier URLs.
Most typical use I see/use is for IDs and other things that really don't need to be on the page for any other reason than its needed at some point to be sent back to the server.
-edit, should've included more detail-
say for instance you have some object you want to update -- the UI sends back a collection of values and the server at that point may or may not know "hey this is a customer object" so you fire off a request to the server and say "hey, give me ID 7" and now you have your customer object as the system knows it. The updates are applied, validated, whatever and now your UI gets the completed result.
I guess a good excuse/argument is using linq. Try to update an object in linq without getting it from the DB first. It has no real idea that it's something it can keep track of until you get the full object.
heres one reason, convenient way of passing data between client code (javascript) and server side.
There are many useful scenarios.
One is to "store" some data on a page which should not be entered by a user. For example, store the user ID when generate a page, then this value will be auto-submitted with the form back to the server.
One other scenario is security. Add some hidden token to the page and check its existence on the server. This will help identify whether a form was submitted via the browser or by some bot which just posted to some url on your site.
It keeps things out of the URL (as in the querystring) so it keeps that clean. It also keeps things out of Session that may not necessarily need to be in there.
Other than that, I can't think of too many other benefits.
They are generally used to store state as an interaction progresses. Cookies could be used instead, but some people disable them. Could also use a single hidden field to point at server-side state, but then there are session-stickiness issues.
If you are using hidden field in the form, you are increasing the burden of form by including a new control.
If there is no need to take hidden field, you should't take it because it is not suitable on the bases of security point. using hidden field does not come under the good programming. Because it also affect the performance of application.

Query String Parameters make my app at risk?

I'm writing an Asp.Net WebForms app where I am calling an edit page an passing in the data about the record to be edited using query string parameters in the URL.
Like:
http://myapp.path/QuoteItemEdit.aspx?PK=1234&DeviceType=12&Mode=Edit
On a previous page in the app, I have presented the user with a GridView of screened items he can edit based on his account privileges, and I call the edit page with these above parameter list, and the page know what to do. I do NOT do any additional checking on the target page to validate whether the user has access to the passed in PK record value as I planned to rely on the previous page to filter the list down and I would be fine.
However, it is clear the user can now type in a URL to a different PK and get access to edit that record. (Or, he may have access to Mode=View, but not Mode=Edit or Mode=Delete. Basically, I was hoping to avoid validating the record and access rights on the target page.
I have also tested the same workflow using Session variables to store PK, DeviceType, and Mode before calling the target page, and then reading them from Session in the target page. So there are no query string paramaters involved. This would take control away from the user.
So, I'm looking for feedback on these two approaches so that I choose an accepted/standard way of dealing with this, as it seems like a very common app design pattern for CRUD apps.
Agreed, you'll want to validate permissions on the target page, it's the only way to be absolutely sure. When it comes to security, redundancy isn't a bad thing. Secure your database as if you don't trust the business layer, secure your business layer as if you don't trust the UI, and secure the UI as well.
You should always validate before the real execution of the action, especially if passing the parameters by query string. For the second page that does the execution you might not need as much feedback for the user since you do not have to be nice to the user if he tries to cirumvent your security, so error handling should be a lot easier.
Passing the variables per session is acceptable but imho you should still validate the values.
We always use querystrings so records can be bookmarked easily, however always validate in both places, if you write you access control code nicely it should just be a case of re-using the existing code...
I believe the common practice is to do what you're avoiding: On the original page, you need to check to see what the user should have capabilities to do, and display their options appropriately. Then on the actual work page, you need to check the user again to verify they are allowed to be there, with access to that specific task.
From a usability standpoint, this is what the user would want (keeps it simple, allows them to bookmark certain pages, etc), and security on both pages is the only way to do this.
If you really don't want to check access rights on the target page:
You could hash the PK with the UserID and then add the hash value to the query string.
string hash = hashFunction(PK.toString() + UserID.toString());
Then you have to make sure the hash in the queryString equals the hash value calculated before loading the page.
Assuming this is an internal organization Web application.
Session variables can be manipulated as well, although not as easily. Whatever authentication you're using throughout your site, you should definitely use on your target page as well. Otherwise, you'll be open to exposing data you may not want as you have found out.
You could do the following to make your URLs a bit more secure:
-Use Guids for Primary Keys so users cant guess other record ID's
-The Mode couls be implicit: Guid = Edit, no Guid = New
and..
-Server-side validation is the only way to go.

Is my gridview paging/sorting inefficient?

I'm using a web service which returns a list of products. I created a Grid View programmatically and used the list as the datasource. However, I can't use the Paging/Sorting methods as it causes errors since I'm not using an ObjectSource control. I handled the paging and sorting manually, but I don't know if I'm doing it efficiently.
When the user clicks on a new page, I handle the page index changing like this:
protected void gvProductList_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
userProducts = Data.GetProductList();
this.gvProductList.PageIndex = e.NewPageIndex;
this.gvProductList.DataSource = userProducts;
gvProductList.DataBind();
}
However, the database is always called when I change pages. Is there a way to make this more efficient, or is that normal for paging? The same goes for sorting, which uses the web service to get the products, then uses a lambda expression to sort the products according to various columns. Each time this happens, the database is called (in order to get the list of products again). Am I handling this wrongly? I know I can use sessions and such to store the List, but there can be hundreds of custom objects per list and tens of thousands of users at any one time.
I should note that the web service is provided by a third party (and so it's their database being called), which means I won't have access to the SQL Server itself nor any methods to change the web service.
Thanks for any help.
EDIT: I should mention that the product list is the user's shopping cart. Therefore, it's unique per user.
General Consensus: If the shopping cart isn't holding many items, the current method would be okay. However, if caching is required, this can be achieved by either using In Proc sessions, or storing sessions on a SQL Server.
No, it's not efficient since you are bringing back every record in the underlying database (presuming GetProductList() returns all records). The GridView paging just means it only shows the number of rows defined in PageSize for the given PageIndex - but it doesn't effect how many records are actually returned from the datasource.
Unfortunately, since you don't have direct access to the database and the web-service doesn't offer any other methods, then the best you can probably do is cache the data. Luckily asp.net makes cacheing data quite simple. The Cache object is rather like Session, except you only have one instance per application, not per user.
It looks like you're fetching all products from the web service, then doing the sorting and paging from within your web page. This means that you're pulling back more data from the web service than you need at any one time. Does the web service provide the facility to pass arguments representing the required page, page size and sort order? If not, maybe you should discuss the possibility of adding these features with the third party who are providing the service.
If this isn't possible, how often is the product list updated? If it is updated relatively infrequently, you could use the ASP.NET cache to store the results of the web service call locally. The cached data source could be set to expire on, say, an hourly basis. This way, users viewing the page will see a reasonably up-to-date list of products.

Resources