39

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); 
 } 
asked Nov 7, 2010 at 23:08

1 Answer 1

42

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
 });
Chuck Norris
15.2k15 gold badges96 silver badges128 bronze badges
answered Dec 1, 2010 at 17:17

4 Comments

It's important to note here that one of the changes you made to your javascript code was that the parameter names are not in quotes. Instead of {"Invoice Number": its {InvoiceNumber:, which I'm assuming was a portion of your problem.
@Mattygabe That really shouldn't matter.
When would you use JSON.stringify vs JSON.Encode? I seem to only have luck using JSON.Encode with the model binder in MVC4.
How does this work? 'myController' appears only once in your example

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.