Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AJAX Post to ASP.NET MVC 6 Controller action method and parameters are null

I am having a strange problem with ASP.NET MVC and sending an AJAX post. I have an anchor tag on the page with id 'lnkGetExpirDates'. When the user clicks it I am trying to simply send this hardcoded data to my controller so it can use it as params and return a result back to the page.

However, in the controller the params are always null/default values. Please see my code below and let me know if I am making a silly mistake or something.

Here is my AJAX post:

$("#lnkGetExpirDates").click(function () {
    e.preventDefault();

    var data = {
        StartDate: "1/19/2016",
        EndDate: "4/19/2016",
        ProductType: "New",
        Count: 1
    };


    $.ajax({
        url: '/Products/GetExpirationDates',
        type: 'POST',
        data: JSON.stringify(data),
        contentType: 'application/json; charset=utf-8',
        dataType: 'html',
        success: function (data) {
            $('#ExpirationDates').val(data);
        }
    });

});

Here is my controller's action method:

// POST: Product/GetExpirationDates
[HttpPost]
//[ValidateAntiForgeryToken]
public IActionResult GetExpirationDates(GetExpirationDatesViewModel vm)
{
    // TODO: Get expiration dates and return them in the response

    return View();
}

Here is the GetExpirationDatesViewModel:

public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string ProductType { get; set; }
public int Count { get; set; }

Please note that I have even tried this without using a model at all and simply just adding parameters to the Action Method such as startDate, endDate, productType, and Count and still everything comes in as null.

like image 388
Blake Rivell Avatar asked Feb 16 '16 20:02

Blake Rivell


1 Answers

When you specify the content type value as application/json, the ajax request made to server will send your js object as the Request Payload, in the body of the request (in json format). So in your action method you should use the [FromBody] attribute.

public IActionResult GetExpirationDates([FromBody] GetExpirationDatesViewModel vm)
{
   return View();
}

You should do this when you want to send a complex js object with properties which is again another model/type

But the data you are sending is a flat view model. So you do not really need to json stringify the js object. Also you may remove the content type property as well as you are not going to send a stringified version of a complex js object.

This should work fine.

$.ajax({
    url: '/Products/GetExpirationDates',
    type: 'POST',
    data: data,      
    dataType: 'html',
    success: function (data) {
        console(data);
    }
});

The above code will send the js object as key value pairs (normal form data) and the model binder will be able to map the form data to your view model object in the server. Take a look at this post for more detailed explanation.

Also i recommend you to use the Url.Action helper method to generate the proper relative url to the action method(s).

url: '@Url.Action("GetExpirationDates","Products")',

The above should work if your js code is inside a razor view. If your code is inside an external js file, Use the solution described in this post.

like image 72
Shyju Avatar answered Oct 17 '22 20:10

Shyju