Jquery Ajax Request and MVC detailed

I have made a post about how to configure the MVC with Razor,Partial View and returning JSON.  It does not need a database – that also because it should be simple to download and see the mechanism.

The sample demonstrates:

  1. Cascading dropdown ( see the button Populate from action and Cascading drop down)
  2. Populating a table from a Partial View(see the button Add New Employee(jquery call action and render)
  3. How to handle  error from action ( press Save 2 )
  4. How to send id parameters (long) from javascript to action ( press Delete 1 or Delete 2)
  5. How to send objects(Employee) from javascript to action ( press Save 1 or Save 2)

The PartialView is made with Razor – but this does not matter. The project can be written as well in ASPX.
asp.net mvc jquery razor cascading demo

I think that a featured programmer will understand fast the code . Now it’s the time for the beginner programmer.

Principles:

  1. Ajax Request in the server should return true or false – never return  error. The error should come from network failure or incorrect IIS server communication.
  2. Cascading dropdowns: return a list and populate the dropdown in the request.
  3. To send only id – as in the url,put {. To send more data,use JSON.Stringify
  4. Returning PartialViews with data : the most easy way is to create an Action,send the data  to this action and return a Partial View. The attempt to re-do the data from an existing DOM Element in javascript is error prone.
  5. A View page must have a ViewModel ( named Model in MVC code ) . The ViewModel can contain data from multiple classes in order to have all data that the View needs. How do you construct this ViewModel ? Simple: think about the data the View needs.

Exemplification :

1.Ajax Request in the server should return true or false – never return  error.

The _Layout in MVC should contain this :

$(document).ready(function () {
            $.ajaxSetup({
                cache: false,
                error: function (x,e) {
                    if (x.status == 0) {
                        alert('You are offline!!\n Please Check Your Network.');
                    } else if (x.status == 404) {
                        alert('Requested URL not found.');
                    } else if (x.status == 500) {
                        alert('Internal Server Error.');
                    } else if (e == 'parsererror') {
                        alert('Error.\nParsing JSON Request failed.');
                    } else if (e == 'timeout') {
                        alert('Request Time out.');
                    } else {
                        alert('Unknown Error.\n' + x.responseText);
                    }
                }
            });
        });

See as the JSON error are handled here – network,timeout,others. And in the server never return error – use this boilerplate

 [HttpPost]
        public JSonResult ....
        {
             try
            {
             var data = obtain data from the server....
   return Json(new {ok = true,mydata=data,message = ""});
            }
            catch (Exception ex)
            {
                return Json(new {ok = false,message = ex.Message});
            }

This way,the only code returned is ok – false or true.
The javascript that call this have this form

 $.ajax({
            type:"POST",
            url:...,
            data: ....,
            datatype:"JSON",
            contentType:"application/json; charset=utf-8",
            success: function (returndata) {
                if (returndata.ok) {
                    //do something with returndata.mydata
                }
                else {
//this is an error from the server
                    window.alert(' error : ' + returndata.message);
                }

            }
        }
        );

See tha handling of if (returndata.ok)
2.Cascading dropdowns: return a list and populate the dropdown in the request.

Example in code: from an department id in the first dropdown the code will fill the employees for the department
Always begin with server code .

[HttpPost]
        public JsonResult GetEmployeesForDepartment(long id)
        {
            try
            {
                //in real application made a better load / retrieving
                var emp = new employeeList();
                emp.Load();
                emp.RemoveAll(item => item.iddepartament != id);
                
                return Json(new { ok = true,data = emp,message = "ok" });
            }
            catch (Exception ex)
            {
                return Json(new { ok = false,message = ex.Message });
            }
        }

As you the first principle ( handle errors ) is applied and the data is filled and returned by

return Json(new { ok = true,data = emp,message = “ok” });

Then wrote an event( here cascadingdropdown) for the first dropdown

<select id="cmbDept" style="display:none" onchange="javascript:cascadingdropdown()"> 
</select>

Then code it

 function cascadingdropdown() {
        var idDept = $("#cmbDept").val();
        window.alert(" call cascading dropdown for iddepartment = " + idDept);
        var urlemp = '@Url.Action("GetEmployeesForDepartment")';
        var select = $('#cmbEmp');
        $.ajax({
            type: "POST",
            url: urlemp,
            data: { id: idDept },
            success: function (returndata) {
                if (returndata.ok) {

                    window.alert('employee data is on javascript,populating combo ');
//empty the combo
                    select.empty();
//fill again 
                    $.each(returndata.data,function (index,itemData) {

                       
                        select.append($('<option></option>').val(itemData.IdEmployee).html(itemData.NameEmployee));


                    });
                    select.show('slow');
                }
                else {
                    window.alert(' error : ' + returndata.message);
                }

            }
        }
        );

    }

The filling of the second dropdown occurs on
$.each(returndata.data,function (index,itemData) {
3. To send only id – as in the url,put {. To send more data,use JSON.Stringify
The code is when you press “Save” or “Delete” . For saving we should send the Name and the department id. For Delete,just the id.
Let’s begin with delete
In server code delete Action have only the id of the employee as a parameter:

    public ActionResult DeleteEmployee(int id)
        {
//just delete it - not important code

So the client code will be simple:

function deleteEmployee(idemployee){
        window.alert('now delete ' + idemployee);
        var urlDelete = '@Url.Action("DeleteEmployee")';
        $.post(urlDelete,
            {id: idemployee},// see here how we transmit an unique parameter
         function (returndata) 
         {
            if(returndata.ok){
                window.alert(' deleted!');
                $("#emp"+ idemployee).hide('slow');
            }
            else{
                window.alert(' error : ' + returndata.message);                
            }

        });

So you see how the
DeleteEmployee(int id)
from server code correspond with
{id: idemployee}
from the client browser.

For saving an employee we will be happy to receive the Employee class:

[HttpPost]
        public ActionResult SaveEmployee(employee emp)
        {

To receive such a parameter we will replicate employee structure in Javascript

function saveEmployee(idemployee) {
        window.alert('now save ' + idemployee);
        var urlSave= '@Url.Action("SaveEmployee")';
        var dept = $("#item_cmbemp" + idemployee).val();
        var name = $("#txtemp" + idemployee).val();
        //replicated structure as the emnployee class in server C# code
        var emp = {
            IdEmployee: idemployee,
            NameEmployee: name,
            iddepartament: dept
        };
        $.ajax({
            type:"POST",
            url:urlSave,
            data:JSON.stringify(emp),//use this in order to MVC binding to take place 
            datatype:"JSON",
            contentType:"application/json; charset=utf-8",
            success: function (returndata) {
                if (returndata.ok) {
                    window.alert(' saved ');                    
                }
                else {
                    window.alert(' error : ' + returndata.message);
                }

            }
        }
        );

    }

So you see how the class instance parameter <strong>emp from server
SaveEmployee(employee emp)
corresponds with the client browser emp structure that is stringified to send to the server

 var emp = {
            IdEmployee: idemployee,
            NameEmployee: name,
            iddepartament: dept
        };

4. Returning PartialViews with data :
Use the same Partial View that you use it for rendering an edit.

public ActionResult AddNewEmployee()
        {
            
            EditEmployeeViewModel evm = new EditEmployeeViewModel();
            evm.DepartmentList = new departmentList();
            evm.DepartmentList.Load();
            evm.Employee = new employee(0,&quot;New !&quot;,evm.DepartmentList[0]);
            return PartialView(&quot;~/Views/Shared/EditorTemplates/EditEmployeeViewModel.cshtml&quot;,evm);//TODO: use T4MVC
        }

And javascript code:

 function AddNew() {
        var urlAdd='@Url.Action(&quot;AddNewEmployee&quot;)';
        $.get(urlAdd,function (data) {
            window.alert(' new employee coming from action !');           
            $('#tableEmp &gt; tbody:last').after( data);//add last the whole data
        });


    }

We are using a simple get – and we have “cached” to false ( see rule 1)

4. A View page must have a ViewModel ( named Model in MVC code ) . The ViewModel can contain data from multiple classes in order to have all data that the View needs
Look at the page
asp.net mvc jquery razor cascading demo

It is clear we need the list of department( maybe cached somehow to not query all the time the database) and the employee (id,name) for each row of the table .
So this we will make:

  public class EditEmployeeViewModel
    {
        public departmentList DepartmentList{get;set;}//need the list to put in dropdown
        public employee Employee { get; set; }// the editing employee
        public EditEmployeeViewModel()
        {
            
        }
        public EditEmployeeViewModel(int id)
        {
            DepartmentList = new departmentList();
            DepartmentList.Load();
            var EmployeeList = new employeeList();
            Employee=EmployeeList.LoadId(id);
        }
         
    }

Conclusion

  1. Ajax Request in the server should return true or false – never return error.
  2. Cascading dropdowns: return a list and populate the dropdown in the request.
  3. To send only id – as in the url,put {. To send more data,use JSON.Stringify
  4. Returning PartialViews with data : the most easy way is to create an Action,send the data to this action and return a Partial View.
  5. A View page must have a ViewModel ( named Model in MVC code ) . The ViewModel can contain data from multiple classes in order to have all data that the View needs.

The download is here:
Jquery MVC Razor demo full


Posted

in

by

Comments

26 responses to “Jquery Ajax Request and MVC detailed”

  1. Dmitriy Avatar
    Dmitriy

    good article about jquery and ajax. Thanks)))

  2. shatvani Avatar
    shatvani

    Hi,
    Can you help me, please?
    I have an ASP.NET MVC 3 Ajax method:

    [AjaxOnly]
    public JsonResult GetTasks(String userName, int period)
    {
    JsonResult js = Json(GetTasksByPeriod(userName, period), JsonRequestBehavior.AllowGet);
    return js;
    }
    When I call it from the MVC app, it works perfectly but when I call it from a different html page (not from MVC app) the method works as good as before but the page doesn’t get back any data.

    $(document).ready(function () {
    $.get(“http://localhost:6703/Task/GetTasks?userName=xyz&period=1”, function (data) {
    $(‘#test’).append(data);
    }, “json”);
    });

    In case of the usage of [AjaxOnly] annotation the request gives an error at ActionExecutingContext filterContext.HttpContext.Request.IsAjaxRequest() call, it doesn’t recognise it as an Ajax request.

    Thank you in advance.

  3. shatvani Avatar
    shatvani

    It was a cross domain request problem.
    Thank you.

  4. Wzbn Avatar
    Wzbn

    thanks you a lot !!! Grat article

    1. Maha Avatar
      Maha

      @Wzbn
      em new in mvc4 plz post the full example of gridview Edit update delete

      1. Andrei Ignat Avatar
        Andrei Ignat

        MVC does not have grid view.

  5. Maha Avatar
    Maha

    plz mail me full code

    mahakhan387@gmail.com

    1. Andrei Ignat Avatar
      Andrei Ignat

      There is – at the final of the blog post

  6. Balaji Avatar
    Balaji

    First, Thanks for this wonderful package..I am a beginner. So sorry If my quesiton is so naive.. I dont understand the part like how the EditEmployeeViewModel.cshtml was loaded in the index.html using the one line @Html.EditorFor(m => item);index.html. Can you explain this in little more detail. I know about this template helper. But I dont understand the logic of calling the EditEmployeeList.cshtml.

    1. Andrei Ignat Avatar
      Andrei Ignat

      MVC takes the name of the Model and search a view with same name

        1. Andrei Ignat Avatar
          Andrei Ignat

          Already answered

  7. Andrea Avatar

    Thank you Andrei. A great article that explains very well a lot of things to a beginner like me. One question. I add a row and save it. If I add a second row the line that is positioned above the previous row, just under the rows of the original table: (table.append)
    And ‘necessary after the save of a line is do a reload of the table? How can you control the reload of new ListEmployeesViewModel by js function saveEmployee? Or before the function $(‘#tableEmp > tbody:last’).after( data) in AddRow ?
    Thanks

    1. Andrei Ignat Avatar
      Andrei Ignat

      Not necessary, but good practice 😉

      1. Mae Ceniza Avatar

        hey, Can you help me…

        how can I connect my Javascript to my database?…

        1. Andrei Ignat Avatar
          Andrei Ignat

          Exactly like in the current post

        2. rakesh Avatar

          with wire

  8. dipti Avatar
    dipti

    Please help me!
    How to add temp data in jqgid???

    1. Andrei Ignat Avatar
      Andrei Ignat

      Put into ViewBag

  9. Crazycow Avatar
    Crazycow

    Thank you. This was most helpful, and helped me to understand the detail of how the code works.
    Many thanks.

  10. Tahir Avatar
    Tahir

    Hi sir,

    I am having a little bit code which auto post the disc level on change event. but i want to do this through AJAX which will not then refresh the page.

    this is controller code…

    public ActionResult updatdisc(int ID, int? discuount, int? page, int? store_id)
    {
    Cust_Det e = (from e1 in db.Cust_Det

    where e1.Cust_Acc_No == ID

    select e1).First();

    e.Disc_Level = discuount;
    db.SaveChanges();

    // return View();
    return RedirectToAction(null, new RouteValueDictionary(new { controller = “Customer”, action = “Index”, page = page, store_id = store_id }));

    }

    this is JS code.

    //auto post drobdownlist
    function mydropdown(id) {

    var e = document.getElementById(“ddl” + id).value;
    alert(“Do you want save this Transaction”);
    window.location.href = ‘/Admin/Customer/updatdisc?ID=’ + id + ‘&discuount=’ + e + ‘&page=’ + $(‘#SelectPageIndex’).val() + ‘&store_id=’ + $(‘#searchBy’).val();
    // window.location.href = ‘/Admin/Customer/Index? &page=’ + $(‘#SelectPageIndex’).val() + ‘&store_id=’ + $(‘#searchBy’).val();
    }

    index view code.

    @Html.DropDownList(“ddl” + item.ID, new SelectList(titleList, “Value”, “Text”, item.Cust_Disc_Level), new { onchange = “mydropdown(” + item.ID + “)” })

    kindly convert this code to AJAX for me ,, it will be very very appriciated
    Thanks

    Regards,

    Tahir

    1. Andrei Ignat Avatar
      Andrei Ignat

      This is private work. Please read my post again and then tell where the problem is.

      1. Pragnesh Avatar
        Pragnesh

        Hey Can you help!
        How to work Like and Dislike Button in asp.net.
        just like Facebook in like dislike..

        1. Andrei Ignat Avatar
          Andrei Ignat

          Of course. Did you read my post?

  11. Suman Kumar Sahu Avatar
    Suman Kumar Sahu

    Sir i have this type code its working but i cant get proper alert message please tell me how get proper allert message?

    public PartialViewResult AjaxEditSubmit(SalaryDetails salaryDetails)
    {
    if(ModelState.IsValid)
    {
    BusinessLYR bs = new BusinessLYR();
    bs.UpdateSalary(salaryDetails);
    }
    return PartialView(JsonRequestBehavior.AllowGet);
    }

    function SaveChanges() {
    var objView = {};
    objView.EmployeeName = document.getElementById(“EmployeeName”).value;
    objView.SalaryAmt = document.getElementById(“SalaryAmt”).value;
    console.log(objView);

    $.ajax({
    type: “post”,
    url: ‘/AAAA/AjaxEditSubmit’,
    data: JSON.stringify(objView),
    contentType: “application/json; charset=utf-8”,
    success: function (Result) {
    alert(“Data has Uploaded SucessFully”);
    },
    }).done(function (Result) {
    alert(“Data has upLoaded to the data base”);
    }).error(function () {
    alert(“data has not uploaded to your Databases”);
    })

    }

    1. Andrei Ignat Avatar
      Andrei Ignat

      Maybe you have a javascript error. Press F12 and see on browser console

Leave a Reply

Your email address will not be published. Required fields are marked *