views:

432

answers:

1

I am using jquery to append or remove a <ListItem> (rendered as <option>) from the <ListBox> (rendered as <select multiple="multiple">).

The problem arises when I try to save on PostBack. The correct information is saved to the database. However, when the page is loaded on PostBack instead of the new data from the database being loaded, the old data from the initial <ListBox> is still there.

When I set Response.Expires = 0 and refresh the page that is loaded after PostBack everything is where it needs to be.

I have tried: Response.Cache.SetCacheability(HttpCacheability.NoCache);
Cache.Remove("Add_Product.aspx");

Also to bypass the problems with EventValidation I am setting EnableEventValidation="false".

So my question is how should I approach this problem? Is there an quick and easy way to force PostBack to load the fresh page?

I would rather not have to redirect to the same page after the PostBack.

+2  A: 

If you don't want to redirect to the same page after the postback (following the Post-Redirect-Get pattern, which can actually clean ASP.NET pages up tremendously!), your best options are to:

1) After you save the item to the database, retrieve your ListBox's DataSource and call ListBox.DataBind() again on the postback. (As a sidenote, the necessity of adding all this extra data retrieval and binding code is one of several reasons people move to the PRG pattern when working with ASP.NET.)

2) Modify your codebehind class so that it adds the list item to the relevant WebControl when you post back to the page.

That is, when you save the new value to the database, add the new ListItem to your ListBox control too:

protected void Save_Click(object sender, EventArgs e) {

  // ... Code to save the new value to your database ...
  ListItem newItem = new ListItem(text, value);
  ListBox.Items.Add(listItem);
}

Now the value will be there when ASP.NET renders your HTML.


Edit: added some more detail, to try to explain why there isn't a better solution.

When you add <option> elements to a <select> control on the client, those new option elements are not communicated to the server - there just isn't any mechanism for it.

That can be confusing because, as you've seen, you can still post the dynamically added option values to the server (though only if you turn off EnableEventValidation, which is risky as womp pointed out in comments).

However, unselected option elements are not communicated to web servers during post requests.

The question then is, how can ASP.NET rebuild the correct ListBox contents after a post request? First, it does whatever the code-behind tells it (ListBox.DataBind, ListBox.Items.Add, etc.). Second, if viewstate is enabled, it adds any option values that were saved to viewstate.

ASP.NET could conceivably have added a third rule, "if the posted value for the select list is not already in the ListBox, add that value to the ListBox." But since it is a security risk to allow arbitrary values to be posted to a page (at least when you have established a set of expected values, as with a ListBox), Microsoft decided against it. (Additionally, consider what you would do about dynamically added ListBox values that failed validation - should those be added when the ListBox is rebuilt or not?)

Jeff Sternal
You should also avoid disabling EventValidation - it's there as a security measure to prevent injection into your pages.
womp
Thanks for the input. I am using your first suggestion. However, I feel like there should be a better solution.
Glad to help, though I'm sorry I couldn't give you a more agreeable solution - I've updated the answer with an attempt to explain why there isn't such a thing.
Jeff Sternal