Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC ajax json post to controller action method

I am trying to achieve a JQuery AJAX call to a controller action method that contains a complex object as a parameter. I have read plenty blogs and tried several techniques learned from these. The key post on which I have constructed my best attempt code (below) is the stackoverflow post here .

I want to trigger an asynchronous post, invoked when the user tabs off a field [not a Form save post – as demonstrated in other examples I have found].

My intention is to:

  • Instantiate an object on the client [not the ViewModel which provides the type for the View];
  • Populate the object with data from several fields in the view;
  • Convert this object to JSON;
  • Call the controller action method using the jQuery.Ajax method, passing the JSON object.

The results will be returned as a JSON result; and data will be loaded into fields in the view depending on results returned.

The problems are:

  • If the action method is attributed with the HttpPost attribute, the controller Action method is not invoked (even though the AJAX call type is set to ‘POST’).
  • If the action method isattributed with HttpGet, the values of properties of the parameter are null
  • The ReadObject method throws the error: "Expecting element 'root' from namespace ''.. Encountered 'None' with name 'namespace'".

Hopefully someone can help. Thanks. Code below:

Client js file

 var disputeKeyDataObj = {      "InvoiceNumber": "" + $.trim(this.value) + "",      "CustomerNumber": "" + $.trim($('#CustomerNumber').val()) + ""   };    var disputeKeyDataJSON = JSON.stringify(disputeHeadlineData);          $.ajax({      url: "/cnr/GetDataForInvoiceNumber",      type: "POST",      data: disputeKeyDataJSON,      dataType: 'json',      contentType: "application/json; charset=utf-8",      success: EnrichedDisputeKeyData(result)   }); 


Action Filter and class for the type associated with the Action method parameter

 [DataContract]    public class DisputeKeyData    {       [DataMember(Name = "InvoiceNumber")]       public string InvoiceNumber { get; set; }      [DataMember(Name = "CustomerNumber")]     public string CustomerNumber { get; set; }  }   

Action method on the controller

  //[HttpPost]   [ObjectFilter(Param = "disputeKeyData", RootType = typeof(DisputeKeyData))]     public ActionResult GetDataForInvoiceNumber(DisputeKeyData disputeKeyData)     {        //Blah!        //....        return Json(disputeKeyData, JsonRequestBehavior.AllowGet);     }   
like image 714
Grant Sutcliffe Avatar asked Nov 07 '10 23:11

Grant Sutcliffe


People also ask

How pass JSON data to AJAX to controller?

ajax({ type: "POST", url: "DATACRUD. json", data: JSON. stringify({data:"test"}), contentType: "application/json; charset=utf-8", dataType: "json", async: false, //_async, success: function (result) { } }); Ajax successfully invokes the action in a controller, but the parameter is null.

How can call action method from jQuery AJAX in MVC?

click(function () { $. ajax({ //base address/controller/Action url: 'http://localhost:51163/Home/Details', type: 'GET', data: { //Passing Input parameter id: $('#txtId'). val() }, success: function (result) { //write something }, error: function () { alert("error"); } }); return false; }); });


1 Answers

Below is how I got this working.

The Key point was: I needed to use the ViewModel associated with the view in order for the runtime to be able to resolve the object in the request.

[I know that that there is a way to bind an object other than the default ViewModel object but ended up simply populating the necessary properties for my needs as I could not get it to work]

[HttpPost]     public ActionResult GetDataForInvoiceNumber(MyViewModel myViewModel)     {                  var invoiceNumberQueryResult = _viewModelBuilder.HydrateMyViewModelGivenInvoiceDetail(myViewModel.InvoiceNumber, myViewModel.SelectedCompanyCode);      return Json(invoiceNumberQueryResult, JsonRequestBehavior.DenyGet);   } 

The JQuery script used to call this action method:

var requestData = {          InvoiceNumber: $.trim(this.value),          SelectedCompanyCode: $.trim($('#SelectedCompanyCode').val())       };         $.ajax({          url: '/en/myController/GetDataForInvoiceNumber',          type: 'POST',          data: JSON.stringify(requestData),          dataType: 'json',          contentType: 'application/json; charset=utf-8',          error: function (xhr) {             alert('Error: ' + xhr.statusText);          },          success: function (result) {             CheckIfInvoiceFound(result);          },          async: true,          processData: false       }); 
like image 122
Grant Sutcliffe Avatar answered Oct 19 '22 14:10

Grant Sutcliffe