Kriya and Meditation for Software / IT Professionals. Conducted by Bipin Joshi in Thane. Read more...
Learn ASP.NET MVC, ASP.NET Core and ASP.NET Design Patterns. Courses conducted by Bipin Joshi on weekends. Click here for more details.

Implementing AutoPostBack in ASP.NET Core

Those of you who worked with ASP.NET web forms will recollect that certain server controls such as DropDownList have a property called AutoPostBack. This property when set to true automatically submits the form to the server whenever the selection changes and raises some server side event. In modern web development people prefer to use Ajax over AutoPostBack but at times AutoPostBack is what you might need. To that end this article shows how AutoPostBack can be implemented in ASP.NET Core applications.

Consider the following web page.

The page consists of two cascading dropdown lists (<select> elements) for displaying countries and states. The values in the country dropdown list can be filled when the page is initially loading in the browser. But the values in the state dropdown list depends on the selection of country. Of course, doing this with jQuery Ajax is quite straightforward. But here our interest do it by implementing AutoPostBack. If you wish to accomplish this task using AutoPostBack then you will do it like this :

  • When the user changes the selection in the country dropdown list you will trap this action.
  • You will set the form's action to some server side MVC action that is responsible for fetching the states for a specific country.
  • You will submit the form to the server.
  • The server executes the MVC action and returns with state dropdown list filled with the required states.

Let's build a sample application that walks you through the process.

Begin by creating a new ASP.NET Core web application. Pick Web Application as the project template while creating the application. This way you will have all the MVC packages added to the project.

Then open the HomeController from under the Controllers folder. You need to add two private helper methods in the HomeController - FillCountries() and FillStates().

The FillCountries() method fills a list of countries in the ViewBag and is shown below:

private void FillCountries(string country="")
{
    List<SelectListItem> countries = new List<SelectListItem>();
    countries.Add(new SelectListItem() { 
Text = "Please select", Value = "Please select" });
    countries.Add(new SelectListItem() { 
Text = "United States", Value = "USA" });
    countries.Add(new SelectListItem() { 
Text = "United Kingdom", Value = "UK" });
    countries.Add(new SelectListItem() { 
Text = "India", Value = "IN" });

    SelectListItem selectedItem = (from i in countries
                                    where i.Value == country
                                    select i).SingleOrDefault();
    if (selectedItem != null)
    {
        selectedItem.Selected = true;
    }

    ViewBag.Countries = countries;
}

The FillCountries() method accepts an optional country parameter. This parameter when present indicates that a particular country from the list should be selected when the page is rendered. Inside, the code creates a List of SelectListItem objects. A SelectListObject object represents an <option> element and holds the Text and Value for that item. Here, we added three countries - India, USA and UK. A first item - Please select - is also added. You can easily replace this code with database driven logic that returns countries from a database table.

Notice that once the List is filled the code also sets the selected item from the list. A country matching the one passed through the parameter is filtered using a LINQ query. Then the Selected property of that SelectListItem object is set to true.

Finally, the List is put inside the ViewBag as Countries property.

The FillStates() helper method is quite similar and is shown below:

private void FillStates(string country="")
{
    List<SelectListItem> states = new List<SelectListItem>();
    switch (country)
    {
        case "IN":
            states.Add(new SelectListItem() 
{ Text = "Maharashtra", Value = "MH" });
            states.Add(new SelectListItem() 
{ Text = "Gujarat", Value = "GJ" });
            states.Add(new SelectListItem() 
{ Text = "Andhra Pradesh", Value = "AP" });
            break;
        case "USA":
            ....
            break;
        case "UK":
            ....
            break;
    }
    ViewBag.States = states;
}

The FillStates() method accepts country parameter that indicates the country for which the states are to be displayed. Inside, a List of SelectListItem is created as before. This time a switch block checks the country value and accordingly adds SelectListItem objects to the List.

Finally, the List is stored in the ViewBag as States property.

Now go to the Index() action and modify it as follows:

public IActionResult Index()
{
  FillCountries();
  ViewBag.StateEnabled = false;
  return View();
}

The Index() action calls FillCountries() in order to add the countries to the ViewBag. Initially since no country has been selected, the states dropdown list should be disabled. So, StateEnabled flag is also stored in the ViewBag. This flag is later used in the view file.

Now add another action to the HomeController - GetStates().

public IActionResult GetStates(string country)
{
  FillCountries(country);
  FillStates(country);
  return View("Index");
}

The GetStates() action is invoked when the user selects a country from the country dropdown list. So, it receives the country value selected by the user. This happens through the normal model binding of ASP.NET Core MVC. Nothing specific needs to be done. Inside, it calls FillCountries() as well as FillStates(). Both these calls receive  the same country as the parameter.

Finish the HomeController by adding a dummy action - ProcessForm() as follows:

public IActionResult ProcessForm()
{
  FillCountries();
  return View("Index");
}

We don't need to implement this method here. This is supposed to be the "final" submit of the page where the whole form is to be processed. We add it just for the sake of completeness.

This completes the controller. Let's shift our attention to the view where the main magic is going to happen.

The Index view consists of a form tag helper and a couple of select tag helpers. Have a look at the markup below:

<form name="form1" asp-controller="Home" asp-action="ProcessForm">
    <h2>Select Country :</h2>
    <select name="country" id="country" 
     asp-items="@ViewBag.Countries" 
     onchange="DoPostBack();">
    </select>
    <br />
    <h2>Select State :</h2>
    <select name="state" id="state" 
     asp-items="@ViewBag.States" 
     disabled="@(ViewBag.StateEnabled == false ? "disabled" : null)">
    </select>
</form>

Observe the markup carefully. The form tag helper sets the asp-controller and asp-action attributes to Home and ProcessForm respectively. The select tag helper showing countries has its name and id attribute set to country. Its asp-item property is set to the ViewBag.Countries. This way Countries List we filled earlier will be bound with the country dropdown list.

The onchange attribute is set to DoPostBack(). This way the client side change event will be handled by the DoPostBack() JavaScript function. The DoPostBack() is discussed in a minute.

The second select tag helper shows a list of states for a country and gets its values from ViewBag.States property. Notice how the disabled attribute is set. Remember the StateEnabled property we set in the Index() action? The code checks this property here. If it is false (means dropdown should be disabled) then disabled attribute is set to disabled. Otherwise, disabled attribute is assigned a null value. It is important to note that a null value (not an empty string) is assigned for this code to work as expected.

 Ok. Now let's add a dash of JavaScript code that actually submits the form.

function DoPostBack()
{
    var select = document.getElementById("country");
    var option = select.options[select.selectedIndex];
    if (option.value != "Please select") {
        document.form1.action = "/home/GetStates";
        document.form1.submit();
    }
}

Write the above function inside a <script> block in the <head> section. The code picks the country dropdown list using getElementById() method. It then finds the selected <option> element using the options array. The value of the selected option item (if not Please select) is the country code such as USA, UK or IN. The code then sets the action property of the form (form1 is the name of the form) to /home/GetStates. This way our form will be handled by GetStates() rather than ProcessForm(). Finally, the form is submitted using the submit() method of the form object.

That's it! Run the application and check whether the AutoPostBack happens as expected. Also check the functioning of cascading dropdown lists.

Although this article was centered around the AutoPostBack, you can use this technique in the following scenarios also:

  • You are not using ordinary submit button to submit a form. Form submission happens on certain event of a certain element. For example, upon clicking an image the form should get submitted.
  • A form has multiple buttons and each button submits to a different action of the controller.

That's it for now! Keep coding!!


Bipin Joshi is a software consultant, an author and a yoga mentor having 22+ years of experience in software development. He also conducts online courses in ASP.NET MVC / Core and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Meditation and Mindfulness to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 31 July 2017


Tags : ASP.NET ASP.NET Core MVC C# Visual Studio