views:

233

answers:

2

Probably a very basic beginner question.

Imagine the following situation:

I have an ASP.NET page with a textbox and a button. In the textbox I enter let's say a name "Laurel" and click the button. The textbox is related as a control parameter to a data source and this data source pulls the content "Laurel" from the textbox to build a query, selects all orders of customer Laurel and sends them back to the browser where they are displayed in a list (gridview for instance). The list is long and has two pages (the list has a pager control). The list is on the same page where also the textbox is located. So I see now a page in my browser with the textbox (still containing the text "Laurel") and a list with a pager.

I could do now two actions:

  • Enter the name "Hardy" in the textbox and click on the button: The cycle above runs again and orders of customer Hardy are displayed. That's fine and what I want.
  • Click on the pager control to display the second page of Laurel's orders. This works because I still have "Laurel" in the textbox. So on the postback triggered by the pager control the data source can extract again "Laurel" as query parameter from the textbox, run the query and deliver the second page of orders to my browser. That's fine too.

Actually there could be a third action:

  • I enter the name "Hardy" in the textbox, then change my mind and decide that I want to see the second page of Laurel's order. So I have "Hardy" in the textbox but don't click the submit button but instead I click on "next page" of the pager control to view the second page. On the server the data source extracts the content "Hardy" of the textbox, runs a query and then tries to deliver the second page of Hardy's instead of Laurel's orders. So that's not what I want. (Perhaps Hardy has only a few orders, not enough for two pages. The data source might tell me then "Nothing found" because there is nothing on the second page for Hardy.)

(What I mean can also be seen here on stackoverflow: Enter something in the search box, for instance "ASP.NET" and hit the enter key, you'll get a long result list with many pages. Then enter another term in the searchbox, for instance "PHP" but don't hit enter, instead click on page 2 in the pager control on bottom of the page. A postback occurs (which also transmits the new content "PHP" of the searchbox, I guess), the second page for keyword "ASP.NET" is displayed and the searchbox doesn't contain "PHP" anymore but instead again "ASP.NET".)

Question is now: How can I avoid a situation like this? My basic idea is: I need to restore the old value "Laurel" in the textbox to provide the correct parameter value to the data source query and my old value "Laurel" must be stored "somewhere" (on server? where on server? on client? if on client, hidden in the page or in a cookie or... ?). Are there some standard patterns to deal with this requirement? Or am I thinking in the wrong direction?

Thank you in advance!

+1  A: 

As you mention in your question, you just need to store the current search term somewhere, and only update it when the Search button is clicked. There are many options:

  • the Session object
  • the ViewState object
  • as a QueryString on the URL
  • a hidden field on the page

Most beginners would choose the Session object, as it is the simplest, but it is also arguably incorrect, as Session is shared across pages and you are dealing with data that pertains to a single page. Therefore, one of the other options would better, from a standards viewpoint.

Jason Berkan
Thanks for your feedback! I just saw that stackoverflow seems to use QueryStrings to store the search term. I understand the solution to utilize the session object and a hidden field. However, I am not sure how to work with the ViewState object. Until now for me this was always an instrument used internally by ASP.NET for state management, nothing intended to be used programmatically. I have to read more about ViewState. Using the session object successfully requires that cookies are accepted in the client browser, is that correct?
Slauma
ViewState and Session access are coded identically - see http://stackoverflow.com/questions/944484/syntax-to-access-variables-in-viewstate. Normally, using the Session does require a cookie, but you can setup cookieless sessions, where the ID is passed in as part of the URL. (http://stackoverflow.com/questions/2273066/what-are-cookieless-sessions)
Jason Berkan
+1  A: 

You could maybe try storing your search term in ViewState when the form is submitted:

private void submitBtn_Click(object sender, EventArgs e) {
    ...
    ViewState["query"] = search.Text;
    ...
}

Then check for this ViewState on postback and set the search.Text property:

private void Page_Load(object sender, EventArgs e) {
    ...
    if (!IsPostBack) {
        ...
    } else {
        ...
        if (ViewState["query"] != null) {
            search.Text = ViewState["query"].ToString();
        }
        ...
    }
    ... 
}

(Stack Overflow is built with ASP.NET MVC so doesn't have to deal with postbacks: instead it's search form uses HTTP GET, which is why you'll see the search terms in the querystring. The search input field is probably re-populated if the search term exists in the querystring and the paging links will probably be built in a similar fashion, hence why you can change the input field, not submit the form but still view page 2, 3, etc. of your original query).

Ian Oxley
Thanks for your reply! I had started to code something very similar to your code example but then I was concerned if I am going the right way. However, in my code I had used `Session` instead of `ViewState`. Jason Berkan in another answer here already explained that accessing ViewState and Session are coded identically. But what is then the difference? Does ViewState have any benefit over Session?
Slauma
The code above has actually a problem with the sequence of page events: Load occurs before Click, thus overwriting the text entered in the TextBox, also in case the button is actually clicked. I have solved this with a private variable, setting it to TextBox.Text at the beginning of Page_Load, and then writing it back to TextBox.Text at the beginning of the click event handler.
Slauma
@Slauma ViewState persists data across postbacks, whereas the Session lasts for the entire duration of a user's visit to a site (unless it times out of course).
Ian Oxley