Cascading Dropdown list in ASP.Net MVC

In this article, I am explaining  how to populate items in
dropdownlist on the basis of another dropdownlist value. I am also using entity
framework code first model to get the list of countries and its states.

·        Open Visual Studio 2010

·        Create a new ASP.Net MVC 3 or 4 web application and named it as CascadingDropDown for this application.

·        Choose Razor as the View engine and click OK

·        Add a Controller in your project and give name as HomeController.

·        Create a model class in the Model folder as shown below:

Country:

    public class Country

    {

        public int CountryID { get; set; }

        public string Name { get; set; }

 

        public virtual ICollection<State> States { getset; }

    }

State:

    public class State

    {

        public int StateID { get; set; }

        public string Name { get; set; }

 

        public int CountryID { get; set; }

        public virtual Country Country { get; set; }

    }

ModelDbContext:

    public class ModelDbContext : DbContext

    {

        public DbSet<Country> Countries { get; set; }

        public DbSet<State> States { get; set; }

    }

Model

In this model class I have created a property CountryID (hold selected value of country), State (hold selected value of state), Countries and States (hold list of available country and its states).

    public class Model

    {

        public int? CountryID { getset; }

        public int? StateID { get; set; }

 

        public IEnumerable<Country> Countries { get; set; }

        public IEnumerable<State> States { get; set; }

    }

Add some sample data in database and intialize it when database has been created:

    public class ModelInitializer : DropCreateDatabaseIfModelChanges<ModelDbContext>

    {

        protected override void Seed(ModelDbContext context)

        {

            var countries = new List<Country>

            {

                new Country

                {

                    Name = “India”

                },

                new Country

                {

                    Name = “USA”

                },

                new Country

                {

                    Name = “South Africa”

                },

                new Country

                {

                    Name = “Australlia”

                },

            };

 

            var states = new List<State>

            {

                new State

                {

                    Name = “Delhi”, Country = countries.Single(m => m.Name == “India”)

                },

                new State

                {

                    Name = “Mumbai”, Country = countries.Single(m => m.Name == “India”)

                },

                new State

                {

                    Name = “California”, Country = countries.Single(m => m.Name == “USA”)

                },

                new State

                {

                    Name = “Newyork”, Country = countries.Single(m => m.Name == “USA”)

                },

                new State

                {

                    Name = “Capetown”, Country = countries.Single(m => m.Name == “South Africa”)

                },

                new State

                {

                    Name = “Bolavia”, Country = countries.Single(m => m.Name == “South Africa”)

                },

                new State

                {

                    Name = “Sydney”, Country = countries.Single(m => m.Name == “Australlia”)

                },

                new State

                {

                    Name = “Melbourne”, Country = countries.Single(m => m.Name == “Australlia”)

                },

            };

 

            countries.ForEach(m => context.Countries.Add(m));

            states.ForEach(m => context.States.Add(m));

        }

    }

Add a connection string in the web.config file under the configuration tag:

<connectionStrings>

    <add name=ModelDbContextconnectionString=Data
Source=.\SQLEXPRESS; Initial Catalog=CountryDb; Integrated Security=true;
providerName=System.Data.SqlClient/>

  </connectionStrings>

Modify the Global.asax file as shown below:

 protected void Application_Start()

        {

            Database.SetInitializer(new CascadingDropDown.Models.ModelInitializer());

            AreaRegistration.RegisterAllAreas();

 

            WebApiConfig.Register(GlobalConfiguration.Configuration);

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

            RouteConfig.RegisterRoutes(RouteTable.Routes);

        }

Create a HomeController and add the following action methods. In this controller, Index action return a Model type object to Index view by holding the list of countries from the database. SelectCountry action return a list of state on the basis of country id.

ModelDbContext db = new ModelDbContext();

 

        public ActionResult Index()

        {

            Model model = new Model

            {

                Countries = db.Countries.ToList()

            };

 

            return View(model);

        }

 

        [HttpPost]

        public virtual ActionResult SelectCountry(int? countryid)

        {

            var states = countryid.HasValue ? db.Countries.FirstOrDefault(m => m.CountryID == countryid).States : null;

 

            Model model = new Model

            {

                CountryID = countryid,

                Countries = db.Countries.ToList(),

                States = states

            };

 

            if (Request.IsAjaxRequest())

                return PartialView(“_States”, model);

            else

                return View(“Index”, model);

        }

Add an Index View and modify this as given below:

@model CascadingDropDown.Models.Model

@{

    Layout = null;

}

<!DOCTYPE html>

<html>

<head>

    <meta name=”viewport” content=”width=device-width” />

    <title>Index</title>

    <script src=”@Url.Content(“~/Scripts/jquery-1.7.1.min.js”)” type=”text/javascript”></script>

    <script type=”text/javascript”>

        $(document).ready(function () {

 

            $(‘input[type=submit]’).hide();

 

            $(‘#CountryID’).change(function () {

                $(this).parents(‘form’).submit();

                return false;

            });

 

            $(“form[action$=’SelectCountry’]”).submit(function () {

 

                $.ajax({

                    url: $(this).attr(‘action’),

                    type: ‘post’,

                    data: $(this).serialize(),

                    success: function (response) {

                        $(‘#states’).html(response);

                    }

                });

                return false;

            });

        });

    </script>

</head>

<body>

    <div>

        @using (Html.BeginForm(“SelectCountry”“Home”))

        {

            <fieldset>

                <legend>Countries</legend>

                @Html.DropDownListFor(m => m.CountryID, new SelectList(Model.Countries, “CountryID”, “Name”), “[Please select a Country]”)

                <input type=”submit” value=”Select” />

            </fieldset>

        }

    </div>

    <div id=”states”>

        @Html.Partial(“_States”, Model)

    </div>

</body>

</html>

 

Add a _States partial view.

@model CascadingDropDown.Models.Model

<fieldset>

    @if (Model.States != null
&& Model.States.Count() > 0)

    {

            <legend>States</legend>

            @Html.HiddenFor(m => m.CountryID);

            @Html.DropDownListFor(m => m.StateID, new SelectList(Model.States, “StateID”, “Name”), “[Please select a state]”)

    }

    else

    {

        <legend>No states available</legend>

    }

</fieldset>

 

Now run an application. It will something look like below:

When javacsript is turned off a select button will also be display in the UI in order to populate the states.

When you select the country, it will populate all states in the state dropdown on the basis of selected country. You can see in the below screenshot.

Thanks for reading this article. You can enter your valuable comments and suggestion to improve this article in the comment box.

In order to get the source code of this application, you can also enter your emailid in the comment box.

Upload file using Ajax form and Modal dialog in ASP.Net MVC

In my previous article I have told you about how to use modal dialog to add, edit, find and delete records in asp.net mvc by using razor view engine. In this article I am going to explain and demonstrate how to upload images by using ajax form and modal dialog in ASP.Net MVC.

To build this sample application you must have basic of jquery. I am using entity framewrok code first model to add and update the information in the database.

·        Open Visual Studio 2010

·        Create a new ASP.Net MVC 3 or 4 web application and named it as AjaxFormMVC for this application.

·        Choose Razor as the View engine and click OK

·        Add a Controller in your project and give name as HomeController.

·        Create a model class in the Model folder as shown below:

public class Actor

    {

        public int ActorID { get; set; }

        public string Name { get; set; }

        public string Description { getset; }

 

        [DataType(DataType.ImageUrl)]

        public string Image { get; set; }

    }

    public class ActorDbContext : DbContext

    {

        public DbSet<Actor> Actors { get; set;}

    }

Add a connection string in the web.config file under the configuration tag:

  <connectionStrings>

    <add name=ActorDbContextconnectionString=Data
Source=.\SQLEXPRESS;Initial Catalog=ActorDb;Integrated Security=true;
providerName=System.Data.SqlClient />

  </connectionStrings>

Add a Partial View _ActorList.cshtml in Views/Home folder and add the following code in this partial view:

@model IEnumerable<AjaxFormMVC.Models.Actor>

<p>

    @Html.ActionLink(“Create New”, “Create”null, new { @class = “createActor”, title = “Create Actor” })

</p>

<table style=”border: 1px solid black;” cellpadding=”10″>

    <tr>

        <th>

            @Html.DisplayNameFor(model => model.Name)

        </th>

        <th>

            @Html.DisplayNameFor(model => model.Description)

        </th>

        <th>

            @Html.DisplayNameFor(model => model.Image)

        </th>

        <th>

        </th>

    </tr>

    @foreach (var item in Model)

    {

        <tr>

            <td valign=”top”>

                @Html.DisplayFor(modelItem => item.Name)

            </td>

            <td valign=”top”>

                @Html.DisplayFor(modelItem => item.Description)

            </td>

            <td valign=”top”>

                <img src=”@Url.Content(“~/Content/Actors/” + item.ActorID + “/” + item.Image + “”)” alt=”@item.Name” width=”100px” height=”100px” />

            </td>

            <td valign=”top”>

                @Html.ActionLink(“Edit”, “Edit”new { id = item.ActorID }, new { @class = “createActor”, title = “Edit Actor” })

                |

                @Html.ActionLink(“Delete”, “Delete”new { id = item.ActorID })

            </td>

        </tr>

    }

</table>

Add a view Index and replace with the code given below.

Must include these three files (jquery-1.7.1.min.js, jquery-ui-1.8.20.min.js, form_ajax.js) under Scripts folder and include themes in the Content folder. Themes folder contain all the necessary CSS files.

@model IEnumerable<AjaxFormMVC.Models.Actor>

@{

    Layout = null;

}

<!DOCTYPE html>

<html>

<head>

    <meta name=”viewport” content=”width=device-width” />

    <title>Index</title>

    <link href=”@Url.Content(“~/Content/themes/base/minified/jquery-ui.min.css”)” rel=”stylesheet” type=”text/css” />

    <script src=”@Url.Content(“~/Scripts/jquery-1.7.1.min.js”)” type=”text/javascript”></script>

    <script src=”@Url.Content(“~/Scripts/jquery-ui-1.8.20.min.js”)” type=”text/javascript”></script>

    <script src=”@Url.Content(“~/Scripts/form_ajax.js”)” type=”text/javascript”></script>

    <script type=”text/javascript”>

        $(document).ready(function () {

 

            $.ajaxSetup({ cache: false });

 

            $(“.createActor”).live(“click”, function (e) {

                var $url = $(this).attr(‘href’);

                var $title = $(this).attr(‘title’);

 

                var $dialog = $();

                $dialog.empty();

                $dialog.load($url).dialog({

                    autoOpen: false,

                    title: $title,

                    resizable: false,

                    height: 300,

                    width: 380,

                    show: { effect: ‘drop’, direction: “up” },

                    modal: true,

                    draggable: true

                });

                $dialog.dialog(‘open’);

                return false;

            });

 

            $(“#btncancel”).live(“click”, function(e) {

                $(“#modalDialog”).dialog(‘close’);

            });

        });  

    </script>

</head>

<body>

    <div id=”actorList”>

        @Html.Partial(“_ActorList”, Model)

    </div>

</body>

</html>

Add a _Actor.cshtml partial view in the same folder Views\Home and add the following code:

@model AjaxFormMVC.Models.Actor

<script type=”text/javascript”>

    $(document).ready(function () {

        $(‘#frmCreateActor’).ajaxForm(function () {

 

            $(‘#modalDialog’).dialog(“close”);

 

            $.post(@Url.Action(“GetActorList”“Home”)function (data) {

                $(“#actorList”).html(data);

            });

        })

    });

</script>

@using (Html.BeginForm(“Create”“Home”, FormMethod.Post, new { @id = “frmCreateActor”, @enctype = “multipart/form-data”
}))

{

    @Html.ValidationSummary(true)

 

    <fieldset>

        <legend>Actor</legend>

        <div class=”editor-label”>

            @Html.LabelFor(model => model.Name)

        </div>

        <div class=”editor-field”>

            @Html.EditorFor(model => model.Name)

            @Html.ValidationMessageFor(model => model.Name)

        </div>

        <div class=”editor-label”>

            @Html.LabelFor(model => model.Description)

        </div>

        <div class=”editor-field”>

            @Html.EditorFor(model => model.Description)

            @Html.ValidationMessageFor(model => model.Description)

        </div>

        <div class=”editor-label”>

            @Html.LabelFor(model => model.Image)

        </div>

        <div class=”editor-field”>

            <input type=”file” name=”imageFile” id=”imageFile” />

            @Html.ValidationMessageFor(model => model.Image)

        </div>

        <p>

            @if (ViewBag.IsUpdate !=null && ViewBag.IsUpdate)

            {

                @Html.HiddenFor(model => model.ActorID);

                <input name=”cmd” type=”submit” value=”Update” />

            }

            else

            {

                <input name=”cmd” type=”submit” value=”Create” />

            }

            <input type=”button” value=”Cancel” id=”btncancel” />

        </p>

    </fieldset>

}

 

Create object of ActorDbContext in HomeController:

ActorDbContext db = new ActorDbContext();

Add the following actions in HomeController:

        public ActionResult Index()

        {

            return View(db.Actors.ToList());

        }

 

        public ActionResult Create()

        {

            return PartialView(“_Actor”);

        }

 

        [HttpPost]

        public ActionResult Create(HttpPostedFileBase imageFile, Actor model, string cmd)

        {

            try

            {

                if (imageFile != null && imageFile.ContentLength > 0)

                {

                    var fileName = Path.GetFileName(imageFile.FileName);

                    if (cmd == “Create”)

                    {

                        model.Image = fileName;

                        db.Actors.Add(model);

                        db.SaveChanges();

                    }

                    else

                    {

                        var actor = db.Actors.Where(m => m.ActorID == model.ActorID).FirstOrDefault();

                        if (actor != null)

                        {

                            actor.Image = fileName;

                            db.SaveChanges();

                        }

                    }

 

                    var path = Path.Combine(Server.MapPath(“~/Content/Actors/”), model.ActorID.ToString());

                    if (!Directory.Exists(path))

                        Directory.CreateDirectory(path);

                    imageFile.SaveAs(path + “/” + fileName);

                }

            }

            catch {}

 

            return RedirectToAction(“Index”);

        }

 

        public ActionResult Edit(int id)

        {

            var actor = db.Actors.Where(m => m.ActorID == id).FirstOrDefault();

            ViewBag.IsUpdate = true;

            return PartialView(“_Actor”, actor);

        }

 

        public ActionResult Delete(int id)

        {

            var actor = db.Actors.FirstOrDefault(m => m.ActorID == id);

            if (actor != null)

            {

                db.Actors.Remove(actor);

                db.SaveChanges();

            }

            return RedirectToAction(“Index”);

        }

 

        public ActionResult GetActorList()

        {

            return PartialView(“_ActorList”, db.Actors.ToList());

        }

Now, run or debug your application. The application will something look like below:

To create a new actor record, click on Create New and enter the information for actor and browse image. When you click on Create button it will add the record both in the database and folder (Content\Actors\{ActorID}\).

The result will something look like below screenshot after adding above record.

Same way, you can edit and delete the records of actor by using Edit and Delete option given in each row.

Thanks for reading this article. You can enter your valuable comments and suggestion to improve this article in the comment box.

In order to get the source code of this application, you can also enter your emailid in the comment box.

MVC Application using Razor View and Entity Framework

This artice simply demonstrate how to create ASP.NET MVC application using razor view engine and how to use data access technology i.e. Entity Framework(EF) while creating ASP.NET MVC 3 application.
Before creating the MVC 3 Application in Visual studio create a table in the database with name and structure as given below:
CREATETABLE [dbo].[Students]
(
      [ID] [INT] IDENTITY PRIMARY KEY,
      [NAME] [VARCHAR](50),
      [AGE] [INT],
      [CITY] [VARCHAR](50)
)

 

You can create applications using either Visual Basic or Visual C# as the programming language. Select Visual C# on the left and then select ASP.NET MVC 3 for this sample. Name your project “MvcSampleApp” and then click OK.

In the New ASP.NET MVC 3 Project dialog box, select Internet Application. Check Use HTML5 markup and leave Razor as the default view engine.

 

In Solution Explorer, right click the Models folder, select Add, and then select Class.
Name the class Student.
Add the following four properties to the Student class:
public class Student
{
        public int ID
        {
            get;
            set;
        }
 
        public string NAME
        {
            get;
            set;
        }
 
        public int AGE
        {
            get;
            set;
        }
 
        public string CITY
        {
            get;
            set;
        }
}

 

We’ll use the student class to represent student in a database. Each instance of a Student object will correspond to a row within a database table, and each property of the Student class will map to a column in the table.
In the same file, add the following StudentDbContext class
public class StudentDbContext : DbContext
{
        public DbSet<Student>Students
        {
            get;
            set;
        }
}

 

The StudentDbContext class represents the Entity Framework student database context, which handles fetching, storing, and updating Student class instances in a database. The StudentDbContext derives from the DbContext base class provided by the Entity Framework.

 

After adding Model class, open the application root Web.config file.
Add the following connection string to the <configuration> element in the Web.config file.

 

<connectionStrings>
    <add name=StudentDbContextconnectionString=Data
Source=.\SQLEXPRESS; Initial Catalog=sample; Integrated Security=true;
providerName=System.Data.SqlClient/>
</connectionStrings>

 

Add a controller class.
In Solution Explorer, right-click the Controllers folder and then select Add Controller.

 

Select the following options:
·   Controller name: StudentController.
·   Template: Controller with read/write actions and views, using Entity Framework.
·    Model class: Student (MvcSampleApp.Models).
·    Datacontext class: StudentDbContext (MvcSampleApp.Models).
·    Views: Razor (CSHTML). (The default.)

 

Click Add. Visual Web Developer creates the following files and folders:
·   A StudentController.cs file in the project’s Controllers folder.
·   A Student folder in the project’s Views folder.
·   Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml, and Index.cshtml in the new Views\Student folder.

 

After adding StudentController, add a HomeController (the default controller) as shown below:

Modify the Index action of HomeController as shown below:
public class HomeController : Controller
{
        public ActionResult Index()
        {
            return RedirectToAction(“Index”, “Student”);
        }
}

 

 
It will redirect to the Index method of Student controller.

 

Now run or debug your application and add some student records. It will something look like as shown below:

 

You can also edit and delete the records and view the details of student.

Further, I am going to explain how to add search functionality in order to search the student by their name and city.

 

Add the following code in the Index.cshtml to implement and display the search functionality to the user. Add the following code below the @Html.ActionLink:

 

@Html.ActionLink(“Create New”, “Create”)
@using (Html.BeginForm(“Index”,”Student”,FormMethod.Get))
{
     <p>City: @Html.DropDownList(“cityList”,“All”)
Name: @Html.TextBox(“stname”)</p>
     <input type=”submit” value=”Search” />
}

 

 
Modify the Index action of StudetController as shown below:

 

public ViewResult Index(string cityList, string stname)
{
            //select all student records
            var students = fromin db.Students
                           select s;
            //get list of cities
            var citylist = from c in students
                           orderby c.CITY
                           select c.CITY;
             //set distinct list of cities in ViewBag property
             ViewBag.cityList = new SelectList(citylist.Distinct());

 

             //search record by city and name
             if (!string.IsNullOrEmpty(stname))
students = students.Where(m => m.NAME.Contains(stname));
             if (!string.IsNullOrEmpty(cityList))
students = students.Where(m => m.CITY == cityList);
            return View(students);
 }

 

Run an application. Now you can easily search the records of student on the basis of their names or city or both.

 

 

Thanks for reading this article.