ASP.NET MVC2 - Checking IsPostBack on load of user control doesn't seem to be correct?
I have a user control which contains the following code:
<form id="CurrencyForm" method="post" runat="server">
Display prices in
<asp:DropDownList ID="currency" runat="server" AutoPostBack="true">
<asp:ListItem Value="GBP">GBP (£)</asp:ListItem>
<asp:ListItem Value="USD">USD ($)</asp:ListItem>
<asp:ListItem Value="EUR">EUR (€)</asp:ListItem>
</asp:DropDownList>
</form>
This user control is included in my Master page so it is available on every page of the site.
Here is the codebehind:
protected void page_load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
currency.SelectedValue = (string)Session开发者_StackOverflow["currency"];
}
else
{
session["currency"] = currency.SelectedValue;
Response.Redirect(Request.RawUrl);
}
}
When I change the selection of the drop down list, a postback is triggered. However, the value of IsPostBack
seems to always be false. I can't quite put my finger on what I am doing wrong here?
Solution
After looking at the advice from the majority of posts I understand I was going wrong by using code_behind code etc instead of the controllers. I figured out how to use an action to basically redirect back to the same page so the following is now what I have:
User control:
<% using (Html.BeginForm("ChangeCurrency", "Home", FormMethod.Post)) {%>
Display prices in
<select id="currency" name="currency">
<option value="GBP">GBP (£)</option>
<option value="USD">USD ($)</option>
<option value="GBP">EUR (€)</option>
</select>
<input type="submit" value="change" /> // this is temporary to test the submit
<%} %>
Action
public ActionResult ChangeCurrency(string currency)
{
Session["currency"] = currency;
return new RedirectResult(Request.UrlReferrer.AbsoluteUri);
}
MVC never does postbacks. Therefore, IsPostBack
will always, correctly, be false. The thing you think is a postback is actually a POST, because MVC doesn't do postbacks. You should not be using the ASP.NET server controls at all in MVC.
I should note that this did used to work in ASP.NET MVC 1. But we made a change in ASP.NET MVC 2 that prevents this from working.
One way or another, the other commenters here are correct: You shouldn't have logic like this in the view because this logic belongs in the controller.
1) lose the code-behind - in MVC "views" (i.e. .aspx or .ascx files) are not meant to contain any codeblocks, just markup and short snippets of code to call properties of the model etc. Also ditch your "runat=server" attributes, and add "name" attributes to all the input elements you're going to post back to the server.
2) set the "action" attribute of the form to a URL on one of your controllers which will handle the post
3) add an action to your controller corresponding to the URL you set above. In it check Request.Form["currency"] to see what value was selected, and set the session variable based on this.
4) from this action, you can return a RedirectResult (? name may be a bit wrong) specifying the original page URL; this will tell the browser to do a "GET" request for the original page after posting the data. (this is known as the post, redirect, get pattern which MVC allows you to make use of, it can be very effective).
5) this won't in itself give you the "auto post on change of value" functionality you were after with autopostback, so I'd add a jQuery script to submit the form on change of value in the drop-down. Something like
$("#currency").change(function(){ $("#CurrencyForm").submit(); });
(which will require you to add a script reference to jQuery if you don't already have one).
I hope that doesn't sound like too much work! Trust me, try it out, embrace MVC and you'll never look back!
Your code is checking Page.IsCallback rather than Page.IsPostback.
If this is MVC, it's setup entirely wrong. MVC eliminates the use for postbacks. You should be using a WebForms project if you need this logic.
精彩评论