Showing posts with label ASP.NET MVC. Show all posts
Showing posts with label ASP.NET MVC. Show all posts

Thursday, 2 June 2016

Dynamic Grid with Dynamic controls for Dynamic data using Telerik KendoUI MVC Grid.

Hi friends,

It was an requirement for one of my project and I had to work hard to achieve this. Hence thought it would be worth sharing with you all.

Problem Statement:
Grid should render data with proper controls (like dropdown for list, datepicker for date, checkbox for bool value etc) to provide edit/add feature in InCell mode (User should be able to edit data within the row).
Below picture will tell you what I mean:




As I said, I used telerik kendoUI ASP.NET MVC controls for this, so here are the prerequisite thing which you need.
1. Kendo.MVC.dll (reference for your project)
2. List of scripts files from KendoUI:
  • jquery.min.js (strongly recommended to use the one which you get from Telerik)
  • kendo.all.min.js
  • kendo.aspnetmvc.min.js 
These js files should be loaded in the same order as it is mentioned here because of dependency. Change in order will throw script error.

3. Use kendo css files for look and feel as per your choice.

These all you will get if you install Telerik KendoUI ASP.NET MVC controls by downloading it from Telerik here.



Here we go for solution:

Because of dynamism of data and controls, your most important task would be, designing the Model for Grid's template and data.

First thing you would need columns metadata information for grid so that you can design grid template for dynamic data and this is what you should have.

FEGridViewModel.cs

 public class FEGridViewModel
    {
        public List<Column> Columns { get; set; }
    }

    public class Column
    {
        public string ColumnName { get; set; }

        public ColumnType ColumnType { get; set; }

        public List<KeyValueData> ListData { get; set; }

        public bool Editable { get; set; }

        public bool Unique { get; set; }
    }

    public class KeyValueData
    {
        public string Name { get; set; }

        public string Value { get; set; }

    }
    public enum ColumnType
    {
        Normal,
        List,
        TrueFalse,
        DateTime
    }


Next we should design the view for grid where we will use this model to design the grid template.

View.cshtml
@model FastEditAPI.Models.FEGridViewModel

@(Html.Kendo().Grid<dynamic>()
.Name("dynamicGrid")
.Columns(columns =>
{
    foreach (var cols in Model.Columns)
    {
        if (cols.ColumnType == FastEditAPI.Models.ColumnType.List)
        {
            columns.ForeignKey(cols.ColumnName, new SelectList(cols.ListData, "Value", "Name", cols.ListData.First().Value)).EditorTemplateName("GridForeignKey")
            .Title(cols.ColumnName);
        }
        else if (cols.ColumnType == FastEditAPI.Models.ColumnType.TrueFalse)
        {
            columns.Template(@<text></text>).ClientTemplate("<input type='checkbox' #= " + cols.ColumnName + " ? checked='checked':'' # class='chkbx' />").Title(cols.ColumnName);
        }
        else if (cols.ColumnType == FastEditAPI.Models.ColumnType.DateTime)
        {
            columns.Bound(cols.ColumnName).Format("{0:dd/MM/yyyy}").EditorTemplateName("Date").Title(cols.ColumnName);
        }
        else
        {
            columns.Bound(cols.ColumnName).EditorTemplateName("String");
        }
    }
})
        .ToolBar(toolbar =>
        {
            toolbar.Save();
        })
        .Editable(editable => editable.Mode(GridEditMode.InCell))
        .Pageable()
        .Navigatable()
        .Sortable()
        .Scrollable()
        .DataSource(dataSource => dataSource
        .Ajax()
        .Batch(true)
        .PageSize(20)
        .ServerOperation(false)
        .Events(events => events.Error("error_handler"))
            .Model(model =>
            {
                foreach (var cols in Model.Columns)
                {
                    if (cols.Unique)
                        model.Id(cols.ColumnName);
                    if (!cols.Editable)
                        model.Field(cols.ColumnName, cols.Type).Editable(false);
                }
            })
            .Read(r => r.Action("feGrid_Read", "FE"))
            .Update(r => r.Action("feGrid_Update", "FE"))
            )



Here we go, Based on the column metadata code here will create controls. i.e. if column metadata says it's a List then code will create a drop down. Except this rest other templates are quite straight forward and the dropdown template can be only achieved here through ForeignKey concept.
 columns.ForeignKey(cols.ColumnName, new SelectList(cols.ListData, "Value", "Name", cols.ListData.First().Value)).EditorTemplateName("GridForeignKey")
            .Title(cols.ColumnName);
This ForeignKey concept requires an editor template which you should have under View=>Shared=>EditorTemplates folder with the name of "GridForeignKey" (this name you can provide with your choice but it must be same as provided in above code (as per your view). This is how GridForeignKey.cshtml should be:


GridForeignKey.cshtml
@model object        
@(
 Html.Kendo().DropDownListFor(m => m)      
        .BindTo((SelectList)ViewData[ViewData.TemplateInfo.GetFullHtmlFieldName("") + "_Data"])
)


Next important and interesting thing is model type for grid data which must be of type 'System.Dynamic.dynamic' so we can create dynamically a class of having same properties as the name of columns there in column metadata.

Now let's see how we are going to write/create dataset for grid with dynamic columns name.
Oops I forgot to tell you that, your main action controller's method which will render your view should return the model (I mean FEGridViewModel).

FEController.cs
public ActionResult Index()
        {
            FEGridViewModel model1 = new FEGridViewModel();
            model1.Columns = new List<Column>()
            {
                new Column() { ColumnName = "id", Type = typeof(String), Editable = false, Unique = true, ColumnType = ColumnType.Normal},
                new Column() { ColumnName = "name", Type = typeof(String), Editable = true, Unique = false, ColumnType = ColumnType.Normal},
                new Column() { ColumnName = "corp_name", Type = typeof(String), Editable = true, Unique = false, ColumnType = ColumnType.Normal},
                new Column() { ColumnName = "cc_currency_id", Type = typeof(String), Editable = true, Unique = false, ColumnType = ColumnType.List,
                    ListData = new List<KeyValueData> {
                        new KeyValueData { Name = "Dollars - USD", Value = "Dollars - USD" },
                        new KeyValueData { Name ="Other", Value ="Other" },
                        new KeyValueData { Name ="¥ yen", Value ="¥ yen" },
                        new KeyValueData { Name ="Zimbabwee Dollar", Value ="Zimbabwee Dollar" },
                        new KeyValueData { Name ="French Franc", Value ="French Franc" },
                    }
                },
                new Column() { ColumnName = "delete_flag", Type = typeof(String), Editable = true, Unique = false, ColumnType = ColumnType.List,
                ListData = new List<KeyValueData> {
                        new KeyValueData { Name = "Delete", Value ="Delete" },
                        new KeyValueData { Name = "Not Delete", Value ="Not Delete" },
                    }
                },
                new Column() { ColumnName = "date", Type = typeof(DateTime), Editable = true, Unique = false, ColumnType = ColumnType.DateTime },
                new Column() { ColumnName = "IsActive", Type = typeof(DateTime), Editable = true, Unique = false, ColumnType = ColumnType.TrueFalse },
            };

            return View(model1);
        }



And finally the grid dynamic data will be returned from the controller method "feGrid_Read" of "FE" controller (or whatever details provide in grid UI for event Read based on your code). This controller method will be called through Ajax call by Telerik. Thanks to Telerik to take care such things and making developer life easy.

Now let's create the data set for grid:

public ActionResult feGrid_Read([DataSourceRequest] DataSourceRequest request)
        {
            List<string> strList = new List<string>() { "Dollars - USD", "Other", "¥ yen", "Zimbabwee Dollar", "French Franc" };
            List<dynamic> flexiList = new List<dynamic>();

                for (var i = 1; i <= 30; i++)
                {
                    string curr = strList[new Random().Next(1, 5)];
                    var flexible = new ExpandoObject() as IDictionary<string, Object>; ;
                    flexible.Add("id", (100 + i).ToString());
                    flexible.Add("name", "Data0" + i.ToString());
                    flexible.Add("corp_name", "T");
                    flexible.Add("cc_currency_id", curr);
                    //flexible.Add("cc_currency", new KeyValueData() { Name = curr , Value = curr });
                    flexible.Add("delete_flag", "Not Delete");
                    flexible.Add("date", DateTime.Now.ToShortDateString());
                    flexible.Add("IsActive", i%2==0? true : false);
                    //flexible.Add("flags", new KeyValueData() { Name = "Not Delete", Value = "Not Delete" });
                    flexiList.Add(flexible);
                }
 DataSourceResult dsresult = (flexiList as IEnumerable<dynamic>).ToDataSourceResult(request);
            var serializer = new JavaScriptSerializer();
            serializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJSONConverter() });
            var json = serializer.Serialize(dsresult);
            return new MyJsonResult(json);
}


because of dynamic data we need to serialize data to json manually. Hence you will be required below two classes which I have used in above code, "ExpandoJSONConverter" and "MyJsonResult". Thanks to Telerik again for creating these two classes.

ExpandoJSONConverter.cs
 public class ExpandoJSONConverter : JavaScriptConverter
    {
        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }
        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            var result = new Dictionary<string, object>();
            var dictionary = obj as IDictionary<string, object>;
            foreach (var item in dictionary)
                result.Add(item.Key, item.Value);
            return result;
        }
        public override IEnumerable<Type> SupportedTypes
        {
            get
            {
                return new ReadOnlyCollection<Type>(new Type[] { typeof(System.Dynamic.ExpandoObject) });
            }
        }
    }


MyJsonResult.cs
public class MyJsonResult : ActionResult
    {

        private string stringAsJson;

        public MyJsonResult(string stringAsJson)
        {
            this.stringAsJson = stringAsJson;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            var httpCtx = context.HttpContext;
            httpCtx.Response.ContentType = "application/json";
            httpCtx.Response.Write(stringAsJson);
        }
    }


And we are done.

Thank You for reading. Feel free to provide your valuable feedback.

Thursday, 14 May 2015

Custom Editor Template for a complex type in MVC

Hi,

Here I am going to demonstrate, How we can create a custom editor template for a complex type.

Let's take a scenario, We are building a application where a student can choose subject he/she wants to learn. Student and Subjects information are available in database. Here is corresponding model classes for Student and Subject. This is just an example.
 public class Student
    {
        public string Name { get; set; }
        public string Class { get; set; }
    }

public class Subject
    {
        public int Id { get; set; }
        public string Name { get; set; }

    }

And our UI should be something like this:
 and output should be like this.

There are multiple ways of doing this and easy way to achieve this is using custom editor template. Here I have two model classes "Student" and "Subject" and I can use this model classes as it is, to bind with view. So what to do. Here is the way, We need to create a ViewModel (ViewModel is required when we have more than one model classes for View, as we need in this example.).
Here I am gonna define ViewModel:

    public class StudentViewModel
    {
        public Student Student { get; set; }
        public List<SubjectsOpted> SubjectsOptedFor { get; set; }
    }

    public class SubjectsOpted
    {
        public Subject Subject { get; set; }
        public bool OptedIn { get; set; }
    }


What I did here?,
First, Created a class which has property of Subject class type and a bool type property. Actually purpose of doing this is, "I need custom editor template for this complex type which basically will help us to achieve the kind of UI we need.
Second, Created a class called StudentViewModel which will be used for binding for View.
Third, Will create custom editor for complex type SubjectOpted.

and here are the steps to create Custom Editor Template for complex type:
1. Add a folder called "EditorTemplates"
2. Create a cshtml file with the name of complex type, in this case it will be SubjectsOpted.cshtml.
3. Add code for this view:
    @model MVCEditorTemplatesExample.Models.SubjectsOpted
        @Html.CheckBoxFor(m => m.OptedIn, new { @checked = "checked" })
        @Html.HiddenFor(m => m.Subject.Id)
        @Html.HiddenFor(m => m.Subject.Name)
        @Html.DisplayFor(m => m.Subject.Name) <br />
4. Yeah, we are done with our custom Editor template for complex type.That's it. :)

Hold on, I still need to show you, how to use this template. Create a view and add below code,
@model MVCEditorTemplatesExample.Models.StudentViewModel
<!DOCTYPE html>
<html>
<head></head>
<body>
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")

    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        <div class="form-horizontal">
            <h4>Student</h4>
            <hr />
            @Html.ValidationSummary(true)
            <div class="form-group">
                @Html.LabelFor(model => model.Student.Name, new { @class = "control-label col-md-2" }):
                @Html.EditorFor(model => model.Student.Name)
                @Html.ValidationMessageFor(model => model.Student.Name)
            </div>
            <br />
            <div class="form-group">
                @Html.LabelFor(model => model.Student.Class, new { @class = "control-label col-md-2" }):
                @Html.EditorFor(model => model.Student.Class)
                @Html.ValidationMessageFor(model => model.Student.Class)
            </div>
            <br />
            <div>
                <b>Choose Subjects:</b><br />
                @Html.EditorFor(model => model.SubjectsOptedFor)
            </div>
            <br />
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-default" />
                </div>
            </div>
        </div>
    }
    <br />
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>
</body>
</html>

Take a look of highlighted code here, this is how we need to call editor template. too tough isn't it :). Based on complex type and name we used for template, MVC is smart enough to decide what editor should be called.



Let's also take a look of Post method, How view model data will get posted back. Mind it, it will be very tough task to do. Here is the code:
        [HttpPost]
        public ActionResult Create(StudentViewModel std)
        {
            try
            {
                std.SubjectsOptedFor.Remove(std.SubjectsOptedFor.FirstOrDefault(itm => itm.OptedIn == false));
                return View("View", std);
            }
            catch
            {
                return View();
            }
        }

:) Thanks to MVC model binder, who is smart enough to bind posted data with viewmodel which we created.

At last, in case if you want to see the code of view which I wrote to render the data (as shown in second UI at top), here it is.
@model MVCEditorTemplatesExample.Models.StudentViewModel
<html>
<head></head>
<body>
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table class="table">
        <tr>
            <th></th>
        </tr>
        <tr>
            <td>
                <b>Name:</b> @Html.Label(Model.Student.Name) <br/>
                <b>Class:</b> @Html.Label(Model.Student.Class) <br/>
                <b>Subject Opted for:</b>
                <table>
                    @foreach (var subject in Model.SubjectsOptedFor)
                    {
                        <tr>
                            <td>
                                @if (subject.OptedIn) { 
                                    @Html.Label(subject.Subject.Name)} &nbsp;
                            </td>
                        </tr>
                    }
                </table>
            </td>
        </tr>
    </table>
</body>
</html>

That's it.

Thank You for reading. Don't forget to like it and feel free to give your feedback/comment.

Saturday, 23 February 2013

ASP.NET MVC 3 Dependency Injection using Unity.MVC3


ASP.NET MVC 3 Dependency Injection
Dependency injection (DI) is a design pattern and it is based on separating component behaviour from dependency resolution without object intervention. In other words we can say it removes the tightly coupled dependency between objects and components in collaboration model where there are contributors and consumers.
To know more about Dependency Injection Pattern, Please follow below links:
http://msdn.microsoft.com/en-us/magazine/cc163739.aspx
Dependency Injection is a particular implementation of Inversion of Control (IoC) principle, which says, An Object should not create other object in which they rely. It means the consumer object receives his dependencies inside constructor properties or arguments.
The advantages of using Dependency Injection pattern and Inversion of Control are:
·         Reduces class coupling
·         Increases code reusing
·         Improves code maintainability
·         Improves application testing

In ASP.Net MVC framework we need Dependency Injection to remove dependency between consumer (say controller) and contributors (service/business layer object).

Now let’s move on Implementation of Dependency Injection in ASP.Net MVC 3. Here we will talk about using Dependency Injection inside an MVC controller. We can also use Dependency Injection inside MVC View and MVC Action Filter.

I assume, you already have the knowledge regarding ASP.Net MVC3.
Before starting first thing we have to do is, IoC container which basically create dependency resolver per HTTP request. And I feel let’s not do that as there are lot many open sources available which provides library to do this like Ninject, Unity and so on.

Here I am going to use Unity.MVC3 and will show you, How you can use Dependency Injection inside controller using Unity.MVC3 IoC library. We will discuss to perform CRUD operation

Introduction of Unity.MVC3:
 A library that allows simple Integration of Microsoft's Unity IoC container with ASP.NET MVC 3. This project includes a bespoke Dependency Resolver that creates a child container per HTTP request and disposes of all registered IDisposable instances at the end of the request.

How to get this library: To include this on project, Right click on your MVC3 app solution in visual studio and click on “Manage NuGet Packages” and search of Unity (refer below pic).

Here you have select Unity.MVC3 (Highlighted on) click to install. Once you installed this you can see below highlighted (in pic) dlls reference in your project:

Next step we will create a service(with interface and implementation)  which is basically responsible to communicate with DB.

And then we create the actual service class which perform all my CRUD operation to create, delete, edit and modify user details to the DB.

Now we will create a controller factory class for Unity which implements IControllerFactory interface, extending CreateController and ReleaseController methods to work with Unity. This factory will create the instances of the controllers that work with Dependency Injection.
Note:
A controller factory is an implementation of the IControllerFactory interface, which is responsible both for locating a controller type and for instantiating an instance of that controller type.
The following implementation of CreateController finds the controller by name inside the Unity container and returns an instance if it was found. Otherwise, it delegates the creation of the controller to an inner factory. One of the advantages of this logic is that controllers can be registered by name.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.Practices.Unity;

namespace MyMVC3WebApp.Factories
{
    public class UnityControllerFactory: IControllerFactory
    {
        private IUnityContainer unityContainer;
        private IControllerFactory defaultInnerFactory;

        public UnityControllerFactory(IUnityContainer container)
            : this(container, new DefaultControllerFactory())
        {
        }

        protected UnityControllerFactory(IUnityContainer container, IControllerFactory innerFactory)
        {
            unityContainer = container;
            defaultInnerFactory = innerFactory;
        }

        public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            try
            {
                return unityContainer.Resolve<IController>(controllerName);
            }
            catch (Exception ex)
            {
                return defaultInnerFactory.CreateController(requestContext, controllerName);
            }
        }

        public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            return System.Web.SessionState.SessionStateBehavior.Default;
        }

        public void ReleaseController(IController controller)
        {
            unityContainer.Teardown(controller);
        }
    }
}


Now next steps we have to register this Unity Library. While installing Unity.MVC3 you have observed, there is class called Bootstrapper.cs is been added to the solution including above mentioned dlls (shown in below pic, highlighted one).

Now next step we have to register our service Type inside BuilUnityController method present under Bootstrapper class.

Highlighted code in above pic is to register our service.

And the last step we have to do is, call the Initialize method of the Bootstrapper class from the global.asax.cs file. Shown in below pic

Now we have done with the create part and will see how I am using this inside my controller.
      
Now if you see, controller receives the business object through constructor and use this to perform CRUD operation. So here our controller is no more depended on creation object of service class on which it relays.

Please feel free to give your suggestion/feedback.

Thank You for reading this.  

References:

Wednesday, 22 August 2012

Custom Handle Error Attribute to handle exception in MVC 3 app


Frnds.
In this post I am going to explain, How can we handle error in MVC  application through common custom error attribute.
First create the custom Error Handler Attribute class. So here is our attribute class:
 public class HandleExceptionAttribute : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            filterContext.ExceptionHandled = true;

            string controllerName = filterContext.RouteData.Values["controller"].ToString();
            string actionName = filterContext.RouteData.Values["action"].ToString();
            string exceptionMessage = string.Empty;

            //You may not need this tracing code. Ignore it!
            Trace.TraceError("Controller = {0} : Action = {1} : Message = {2} : StackTrace = {3}",
                controllerName,
                actionName,
                filterContext.Exception.Message,
                filterContext.Exception.StackTrace);

            //Below is the switch case to handle error for all the controller class in our
            //MVC application at one place.
            switch (controllerName)
            {
                case "State":
                    switch (actionName)
                    {
                        case "Create":
                            actionName = "Index";
                            exceptionMessage = "Sorry, an error occured on creating new State, Please try again.";
                            break;
                        case "Edit":
                            actionName = "Index";
                            exceptionMessage = "Sorry, an error occured on editing new State, Please try again.";
                            break;
                        case "Delete":
                            actionName = "Index";
                            exceptionMessage = "Sorry, an error occured on deleting new State, Please try again.";
                            break;
                        default:
                            break;
                    }
                    break;
                case "Account":
                    switch (actionName)
                    {
                        case "Register":
                            controllerName = "Register";
                            actionName = "Index";
                            exceptionMessage = "Sorry, an error occured on registering new User, Please try again.";
                            break;
                        case "Login":
                            controllerName = "Login";
                            actionName = "Index";
                            exceptionMessage = "Sorry, an error occured on Login, Please try again.";
                            break;

                    }

                    break;
            }

            //Creating ViewData Dictionary which will hold the error info to show to the end user.
            ViewDataDictionary viewData = new ViewDataDictionary();
            viewData.Add(new KeyValuePair<string, object>("controller", controllerName));
            viewData.Add(new KeyValuePair<string, object>("action", actionName));
            viewData.Add(new KeyValuePair<string, object>("message", exceptionMessage));

            //Calling error page inside shared folder to show the proper error message.
            filterContext.Result = new ViewResult { ViewName = "Error", ViewData = viewData };
        }
    }
Above attribute will help to handle error. You can add your controller and action method in switch case
statement as per your need.

Now Next step we will see how to use this attribute.
        [HandleException]
        public ActionResult Edit(StateModel stateModel)
        {
            try
            {
                // TODO: Add update logic here
                throw new InvalidOperationException();
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }
Since my Custom Error Handler Attribute  is written to handle error for each action of controller so I need to use it before my action method. In above code [HandleException] attribute  will execute our Custom Handle Attribute class code written here in case of any error.
Next step we need to modify/create the error  page (Error.cshtml) inside shared folder to show the error message to the end user.
@{
    ViewBag.Title = "Error";
}

<h2>
    Sorry, @ViewData["message"].<br />
    <a href="@Url.Action(ViewData["action"].ToString(),ViewData["controller"].ToString())">Back</a>
</h2>
Note: Modify the above code as per your need and enjoy.
Thank You for reading.

CRUD operation using MVC3 and Jquery


Frnds,
In this post I am gonna write code which is explaining CRUD operation using MVC WebGrid and Jquery.
Below Image Gallary shows Grid Data with Paging and Sorting functionality.
   
In this post I am gonna write code which is explaining CRUD operation using MVC WebGrid and Jquery.
 Before proceeding further we need to have our model class. Here is the our model class.
StateModel.cs
namespace MyMVC3WebApp.Models
{
    public class StateModel
    {
        [ScaffoldColumn(false)]
        public int StateID { get; set; }

        [Required]
        [StringLength(10)]
        [Remote("StateNameExist","State")]
        public string StateName { get; set; }

        [Required]
        [StringLength(10)]
        public string CountryName { get; set; }
    }
}
In our above model class I have implemented basic validation including Custom Remote validation which actually checks
State Name existence into the DB before submitting form. Here Remote attribute has two parameters, first one is action method name and the second one is the Controller name.
Above code will help you to understand the basic CRUD operation for data. Please give your feedback if you really like it or if you have any suggestion here.
Now let’s create our controller class which will have the code for the database operation.
StateController.cs
namespace MyMVC3WebApp.Controllers
{
    public class Country
    {
        public string Name { get; set; }
    }

    public class StateController : Controller
    {

        private TestDataEntities db = new TestDataEntities();
      //Method which returns list of country for dropdown country selection.
        public JsonResult GetCountries()
        {
            List<Country> resultset = new List<Country>() {
                new Country(){Name="India"},
                new Country(){Name="US"},
                new Country(){Name="Australia"},
                new Country(){Name="Rusia"},
            };
            return Json(resultset, JsonRequestBehavior.AllowGet);
        }
//Method to check state name existence being called by Remote attribute implemented in Model class for validation.
        public JsonResult StateNameExist(string stateName)
        {
            int count = (from states in db.StateMasters.AsEnumerable()
                         where states.StateName.ToLower().Trim() == stateName.ToLower().Trim()
                         select states.StateName).Count();
            if (count > 0)
                return Json(string.Format("State name {0} already exists.", stateName), JsonRequestBehavior.AllowGet);
            else
                return Json(true, JsonRequestBehavior.AllowGet);

        }
//Method returns list of states.
        public ActionResult Index()
        {
            IEnumerable<StateModel> states = from st in db.GetAllStates()
                                             select new StateModel() { StateID = st.StateID, StateName = st.StateName, CountryName = st.CountryName };
            return View(states.ToList<StateModel>());
        }

        //
        // GET: /State/Details/5

        public ActionResult Details(int id)
        {
            return View();
        }

        //
        // GET: /State/Create

        public ActionResult Create()
        {
            return View(new StateModel());
        }

        //
        // POST: /State/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public void AddNewState(string stateName, string countryName)
        {
            db.AddState(stateName, countryName);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public void UpdateState(int id, string stateName, string countryName)
        {
            StateMaster state = db.StateMasters.Single(s => s.StateID == id);
            state.StateName = stateName;
            state.CountryName = countryName;
            db.SaveChanges();
        }

        [HttpPost]
        public ActionResult Create(StateModel stateModel)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    int result = Convert.ToInt32(db.AddState(stateModel.StateName, stateModel.CountryName));
                }

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        public ActionResult Delete(int id)
        {
            db.DeleteState(id);
            return RedirectToAction("Index");
        }
    }
}
Now this is the right time to create our view as we have ready with our model and controller class.
Index.cshtml

@model IEnumerable<MyMVC3WebApp.Models.StateModel>
@{
    ViewBag.Title = "Index";
}
<h2>
    Index</h2>
<link href="http://1.cdn.blog.com/wp-admin/../../Content/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<link href="http://1.cdn.blog.com/wp-admin/../../Content/themes/base/jquery.ui.dialog.css" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="http://1.cdn.blog.com/wp-admin/../../Scripts/jquery-ui-1.8.11.js" type="text/javascript"></script>
<style>
    body
    {
        font-size: 82.5%;
    }
    label, input
    {
        display: block;
    }
    input.text
    {
        margin-bottom: 12px;
        width: 95%;
        padding: .4em;
    }
    fieldset
    {
        padding: 0;
        border: 0;
        margin-top: 25px;
    }
    h1
    {
        font-size: 1.2em;
        margin: .6em 0;
    }
    div#users-contain
    {
        width: 350px;
        margin: 20px 0;
    }
    div#users-contain table
    {
        margin: 1em 0;
        border-collapse: collapse;
        width: 100%;
    }
    div#users-contain table td, div#users-contain table th
    {
        border: 1px solid #eee;
        padding: .6em 10px;
        text-align: left;
    }
    .ui-dialog .ui-state-error
    {
        padding: .3em;
    }
    .validateTips
    {
        border: 1px solid transparent;
        padding: 0.3em;
    }
    .odd
    {
        background-color: #FFF;
    }
    .even
    {
        background-color: #E8E8E8;
    }

    .grid
    {
        margin: 4px;
        border-collapse: collapse;
        width: 600px;
    }
    .head
    {
        background-color: #E8E8E8;
        font-weight: bold;
        color: #FFF;
    }
    .grid th, .grid td
    {
        border: 1px solid #C0C0C0;
        padding: 5px;
    }
    .alt
    {
        background-color: #E8E8E8;
        color: #000;
    }
    .gridItem
    {
        width: auto;
        font-weight: normal;
        font-style: normal;
    }

    .gridHiddenItem
    {
        visibility: hidden;
    }

    .img
    {
        width: 20px;
        height: 20px;
        text-align: center;
    }
</style>
<script type="text/javascript">
    $(function () {  //$(document).ready(function () {

        //Start-apply css on table data
        $('tr:even').addClass('even');
        $('tr:odd').addClass("odd");
        //End-apply css on table data

        //Start-a workaround for a flaw in the demo system (http://dev.jqueryui.com/ticket/4375), ignore!
        $("#dialog:ui-dialog").dialog("destroy");
        //End-a workaround for a flaw in the demo system (http://dev.jqueryui.com/ticket/4375), ignore!

        //Start-get controls
        var state = $("#stateName"),
   country = $("#countryName"),
            btnDel = $('#deleteRecord'),
   allFields = $([]).add(state).add(country),
   tips = $(".validateTips");
        //End-get controls

        //Start-Json Call to get all country to fill the country dropdown.
        $.getJSON('/State/GetCountries', '',
        function (obj) {
            var html = "";
            for (var i = 0; i < obj.length; i++) {
                html += "<option value='"
                    + obj[i].Name
                        + "'>" + obj[i].Name
                            + "</option>";
            }
            country.html(html);
        }
        );
        //End-Json Call to get all country to fill the country dropdown.

        //Start-apply css for validation error message
        function updateTips(t) {
            tips
    .text(t)
    .addClass("ui-state-highlight");
            setTimeout(function () {
                tips.removeClass("ui-state-highlight", 1500);
            }, 500);
        }
        //End-apply css for validation error message

        //Start-length check validation
        function checkLength(o, n, min, max) {
            if (o.val().length > max || o.val().length < min) {
                o.addClass("ui-state-error");
                updateTips("Length of " + n + " must be between " +
     min + " and " + max + ".");
                return false;
            } else {
                return true;
            }
        }
        //End-length check validation

        //Start-state name existence validation.
        function checkIfStateExist(o) {
            var val = o.val();
            var IsExist = false;
            //synchroneous ajax call
            $.ajax({
                type: 'GET',
                url: '/State/StateNameExist',
                dataType: 'json',
                success: function (obj) {
                    if (obj == true) {
                        IsExist = true;
                    }
                    else {
                        o.addClass("ui-state-error");
                        updateTips(obj);
                        IsExist = false;
                    }
                },
                data: { stateName: val },
                async: false
            });
            return IsExist;
        }
        //End-state name existence validation.

        //Start-Convert div form to model dialog
        $("#dialog-form").dialog({
            autoOpen: false,
            height: 350,
            width: 250,
            modal: true,
            buttons: {
                "Submit": function () {
                    var bValid = true;
                    allFields.removeClass("ui-state-error");
                    //Perform Validation here..
                    bValid = bValid && checkLength(state, "State Name", 3, 45);
                    bValid = bValid && checkIfStateExist(state);
                    if (bValid) {
                        var id = $("#stateID").val();
                        var st = state.val();
                        var ctry = country.val();
                        if (id != "") {
                            url = "/State/UpdateState";
                            $.post(url, { id: id, stateName: st, countryName: ctry }, function (data) {
                                //reload data
                                location.reload();
                            });
                        }
                        else {
                            var url = "/State/AddNewState";
                            $.post(url, { stateName: st, countryName: ctry }, function (data) {
                                //reload data
                                location.reload();
                            });
                        }

                        $(this).dialog("close");
                    }
                },
                Cancel: function () {
                    $(this).dialog("close");
                }
            },
            close: function () {
                allFields.val("").removeClass("ui-state-error");
            }
        });
        //End-Convert div form to model dialog

        //Start-show dialog on create new button click
        $("#create-state")
   .button()
   .click(function () {
       $('#dialog-form').attr('title', 'Create New State');
       $("#dialog-form").dialog("open");
   });
        //End-show dialog on create new button click

        //Start-show dialog on Edit button click
        $("a#editRecord")
   .click(function (obj) {
       $('#dialog-form').attr('title', 'Edit State');
       $("#dialog:ui-dialog").dialog("destroy");
       var trObj = $(this).parents("tr");
       var id = trObj[0].cells[0].lastChild.defaultValue;
       var state = trObj[0].cells[1].innerText.trim();
       var country = trObj[0].cells[2].innerText.trim();
       $("#stateID")[0].value = id;
       $("#stateName")[0].value = state;
       $("#countryName").val(country);
       $("#dialog-form").dialog("open");
   });
        //End-show dialog on Edit button click

    });

    function ConfirmDelete() {
        return confirm('Do you want to delete this record');
    }

</script>

<p>
    <a id="create-state" href="#">Create New</a>
</p>
<div>
    <table>
        <tr>
            <td>
                @{
                    var grid = new WebGrid(Model, canPage: true, rowsPerPage: 5);
                }
                <div id="grid">
                    @grid.GetHtml(
                 tableStyle: "grid",
                headerStyle: "head",
                alternatingRowStyle: "alt",
                columns: grid.Columns(
                    grid.Column(null, null, format: @<input type="hidden" name="ID" value="@item.StateID"/>),
                    grid.Column("StateName", "State", style: "gridItem", canSort: true),
                    grid.Column("CountryName", "Country", style: "gridItem", canSort: true),
                    grid.Column("Edit", format: @<text><a id="editRecord" href="#"><img alt="" src="../../Content/images/Edit.jpg"
                        style="height: 20px; width: 20px" /></a></text>, style: "imgstyle"),
                    grid.Column("Delete", format: @<text><a href="@Url.Action("Delete", "State", new { id = item.StateID })" onclick="javascript:return ConfirmDelete();"><img
                        alt="" src="../../Content/images/delete.png" style="height: 20px; width: 20px" /></a></text>, style: "imgstyle")
)
                )
                </div>
            </td>
        </tr>
    </table>
</div>
<div>
    <div id="dialog-form" title="State">
        <p>
            All form fields are required.</p>
        <form>
        <fieldset>
            <input id="stateID" type="text" style="visibility: hidden" />
            <label for="stateName">
                State</label>
            <input type="text" name="stateName" id="stateName" />
            <label for="country">
                Country</label>
            <select id="countryName" style="width: 95%">
            </select>
        </fieldset>
        </form>
    </div>
</div>
Above view has style, script and html code for the view. starting of this post, post has the output images for the above code. Enjoy!