views:

2399

answers:

1

I am trying to pass JSON data from the client browser to an ASP.NET MVC Action using jQuery $.ajax() and bind it to a .NET class using a custom ModelBinder.

THE CLIENT JAVASCRIPT:

$('#btnPatientSearch').click(function() {

  var patientFilter = {
    LastName: 'Flinstone',
    FirstName: 'Fred'
  };

  var jsonData = $.toJSON(patientFilter);

  $.ajax({
    url: '/Services/GetPatientList',
    type: 'GET',
    cache: false,
    data: jsonData,
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    timeout: 10000,
    error: function() {
      alert('Error loading JSON=' + jsonData);
    },
    success: function(jsonData) {
      $("#patientSearchList").fillSelect(jsonData);
    }
  });

THE .NET CLASS FOR THE JSON DATA

[ModelBinder(typeof(JsonModelBinder))]
public class PatientFilter
{

  #region Properties

  public string IDNumber { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string SSN { get; set; }
  public DateTime DOB { get; set; }

  #endregion
}

THE MVC ACTION

  public JsonResult GetPatientList(iPatientDoc.Models.PatientFilter patientFilter)
  {

THE CUSTOM MODELBINDER

public class JsonModelBinder : IModelBinder
{
  #region IModelBinder Members

  public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  {
    if (controllerContext == null)
      throw new ArgumentNullException("controllerContext");
    if (bindingContext == null)
      throw new ArgumentNullException("bindingContext");

    var serializer = new DataContractJsonSerializer(bindingContext.ModelType);
    return serializer.ReadObject(controllerContext.HttpContext.Request.InputStream);
  #endregion

  }
}

The custom ModelBinder is called correctly, yet the Request.InputStream is empty so there is no data to bind to the PatientFilter object.

Any thoughts appreciated. Chris

+2  A: 

Some thoughts on this

  • You use a GET request. I think the request body is always empty for a GET
  • Your PatientFilter class doesn't have a [DataContract] attribute. I'm not sure if it would serialize anything
  • I'm not sure about your $.ajax() call. I expected that the data option would just take an object instead of a JSON string. After looking at the documentation, I would try to set the processData option to false.

There's also an interesting description for the data option:

Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key i.e. {foo:["bar1", "bar2"]} becomes '&foo=bar1&foo=bar2'.

chris166
I did all 3 of your suggestions and it now works. I'll investigate each individually further to see what the impact of each is on the process.
ChrisP