Multiple postbacks in an MVC page

With my limited (but growing) experience in MVC, I’ve come up with a way to handle multiple postbacks to the same page in MVC. Here’s a simple application:

  • User selects a category from a dropdownlist – causes postback and loads subcategories
  • User selects a sub category and clicks on the submit button
  • A confirmation message appears on the view

Here’s how I’ve implemented it. Created an MVC project and added two classes – Category and SubCategory:

   1:      public class Category
   2:      {
   3:          public int CategoryID { get; set; }
   4:          public string CategoryName { get; set; }
   5:      }
   6:   
   7:      public class SubCategory
   8:      {
   9:          public int SubCategoryID { get; set; }
  10:          public string SubCategoryName { get; set; }
  11:          public int CategoryID { get; set; }
  12:      }

In the HomeController’s Index method (GET version):

   1:  public ActionResult Index()
   2:  {
   3:      var categories = GetCategories();
   4:      var subCategories = GetSubCategories(0);
   5:   
   6:      ViewData["PreviousCategoryID"] = 0;
   7:   
   8:      ViewData["CategoryID"] = new SelectList(categories, "CategoryID", "CategoryName");
   9:      ViewData["SubCategoryID"] = new SelectList(subCategories, "SubCategoryID", "SubCategoryName");
  10:      return View();
  11:  }

The GetSubCategories(0) returns a dummy list taking zero as the default value for the categoryID. I’ll let you know what the ‘PreviousCategoryID’ is in a few. My View looks like this:

   1:  <h2>Movie Guide</h2>
   2:  <% using(Html.BeginForm()) { %>
   3:      <%= Html.Hidden("PreviousCategoryID", ViewData["PreviousCategoryID"]) %>
   4:      <p>
   5:          <%= Html.DropDownList("CategoryID", (SelectList)ViewData["Categories"], 
   6:                                new { onchange = "this.form.submit();" })%>
   7:          <p />
   8:          <%= Html.DropDownList("SubCategoryID", ViewData["SubCategories"] as SelectList)%>
   9:          <p />
  10:          <input type="submit" value="Submit" />
  11:          <p />
  12:          <%= ViewData["Message"] %>
  13:      </p>
  14:  <% } %>

So, the user selects a category from the list and post back occurs. Now, here’s the issue I want cleared off.

In order to determine which control caused the postback, in my Index method (POST version), I check the value of the CategoryID dropdownlist against the PreviousCategoryID. If they are different, I know the postback was caused by the dropdownlist and I populate the SubCategories list based on categoryID.

However, if they are same, I assume the postback was caused by the button click and hence I display the message to the user.

Is this the best way to do the check or am I missing something?

   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public ActionResult Index(FormCollection formCollection)
   3:  {
   4:      var categoryID = int.Parse(formCollection["CategoryID"]);
   5:      var previousCategoryID = int.Parse(formCollection["PreviousCategoryID"]);
   6:   
   7:      // if these are different, then postback was caused by the category dropdownlist
   8:      if(categoryID != previousCategoryID)
   9:      {
  10:          var categories = GetCategories();
  11:          var subCategories = GetSubCategories(categoryID);
  12:   
  13:          ViewData["PreviousCategoryID"] = categoryID;
  14:          
  15:          var categoryList = new SelectList(categories, "CategoryID", "CategoryName", categoryID);
  16:   
  17:          ViewData["Categories"] = categoryList;
  18:          ViewData["SubCategories"] = new SelectList(subCategories, "SubCategoryID", "SubCategoryName");
  19:          return View();
  20:      }
  21:      // if not, assume a button click and show message to user
  22:      else
  23:      {
  24:          var categories = GetCategories();
  25:          var subCategories = GetSubCategories(0);
  26:   
  27:          ViewData["PreviousCategoryID"] = 0;
  28:   
  29:          ViewData["Categories"] = new SelectList(categories, "CategoryID", "CategoryName");
  30:          ViewData["SubCategories"] = new SelectList(subCategories, "SubCategoryID", "SubCategoryName");
  31:          ViewData["Message"] = "Your selected has been noted.";
  32:          return View();
  33:      }
  34:  }

Line 8 is where I check for the difference. If true, PreviousCategorID gets updated with the latest categoryID (line 13) and I can use it in the next postback.

This no doubt works, but seems a little ‘icky’ (sorry for the choice of words.. English IS my second language). Please let me know if there’s a better way to handle this situation.

Thanks
Arun

Published Monday, October 12, 2009 4:57 PM by nmarun
Filed under: ,

Comments

# ASP.NET MVC Archived Buzz, Page 1

Monday, October 12, 2009 7:53 PM by ASP.NET MVC Archived Buzz, Page 1

Pingback from  ASP.NET MVC Archived Buzz, Page 1

# ASP.NET MVC Archived Buzz, Page 1

Monday, October 12, 2009 7:53 PM by ASP.NET MVC Archived Buzz, Page 1

Pingback from  ASP.NET MVC Archived Buzz, Page 1

# re: Multiple postbacks in an MVC page

Monday, October 12, 2009 8:45 PM by worldspawn[]

You also could have checked for the presence of your button (give it a name) in the form collection.

You could also have your dropdownlist javascript change the action attribute of the form to point to another action (thus executing a different method). Triggering another action (in whatever way) would be my first choice.

# re: Multiple postbacks in an MVC page

Monday, October 12, 2009 8:50 PM by Webdiyer

You could use if(!string.IsNullOrEmpty(formCollection["submit"])) to determine if page is submitted by clicking submit button.

# re: Multiple postbacks in an MVC page

Monday, October 12, 2009 9:29 PM by Craig

I think you would be better off using jQuery Ajax to load the subcategory drop down lists. Much better user experience and probably easier anyway.

# re: Multiple postbacks in an MVC page

Monday, October 12, 2009 9:47 PM by AlecWhittington

I agree with Craig. You would be much better off using JQuery to dynamically populate the second drop down. Combine it with the Select box plug-in (www.texotela.co.uk/.../select) and it is a snap

# re: Multiple postbacks in an MVC page

Tuesday, October 13, 2009 12:01 AM by nmarun

Thanks for the input you guys

# re: Multiple postbacks in an MVC page

Tuesday, October 13, 2009 12:16 AM by Hernan Garcia

I think that you should split your action in two different ones: maybe SelectSubcategories and Submit or something like that. Since you relly on js changing the Action for the form is pretty simple.

Both branches of the if statement are practically identicals but are related to different "actions", use extract method to create a private helper method for the common functionality.

If you can't do that check for the submit button to be present, it will make the code more expressive. That's the way we used to do it in classic asp and php.

# Twitter Trackbacks for Multiple postbacks in an MVC page - IBloggable - implemented [asp.net] on Topsy.com

Pingback from  Twitter Trackbacks for                 Multiple postbacks in an MVC page - IBloggable - implemented         [asp.net]        on Topsy.com

# re: Multiple postbacks in an MVC page

Tuesday, October 13, 2009 11:36 AM by Trevor de Koekkoek

You definitely should be using 2 actions with 2 form tags.  Whether you use Ajax or not, you are requesting 2 pieces of data and you should not be using 1 action for this.  Your controller should not have to "know" which button or drop-down or whatever was selected.

# re: Multiple postbacks in an MVC page

Tuesday, May 15, 2012 7:03 AM by Bashar

Developers will want to code in their preferred lnuaagge and C# is the dominant .net lnuaagge, thus the need for a better web framework written in C#. Ruby has Ruby on Rails, and Python has Django.Software is never completely original and is always borrowing and sharing ideas from other code and frameworks. I guess that Microsoft believe that they can improve upon whats out there, and take what already works from the other awesome frameworks such as RoR, Django And MonoRail.In terms of tools its up to the developers to be aware of whats right and whats disgusting, and make better decisions from reading blogs!

Leave a Comment

(required) 
(required) 
(optional)
(required)