skip to Main Content

I have a strange issue doing an ajax post.
The data is sent to the request, but for some reason the data does not arrive in the controller function.

This is my post function:

$.ajax({
    type: 'POST',
    url: url,
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',
    data: data,
    success: function (data) {
        if (data.redirect) {
            window.location.replace(data.redirect);
        } else {
            $(dest).replaceWith(data);
        }
    },
    error: function (xhr, status, err) {
        //alert('Response code:' + xhr.status + 'rn[Error:' + err + '] ' + status);
    }
});

Nothing too uch out of the ordinary there.
When I set a breakpoint in this function I do see the data I expect:
enter image description here

But when I arrive at my controller function the properties of the viewmodel aren’t filled:
enter image description here

I’ve tried to add attributes to the parameter, like [FromBody] and sorts, but most of the time that results in a 415.

The date is retrieved with $("form").serialize() if that would make a difference.

I’ve used the function in the past, when I was still using plain MVC, and this worked back then.
I believe the last time the project was in .NET Core 2.1 and this is running .NET 5, don’t know if that has an impact on how the code should be implemented.

Been struggling with this for several hours, I just need to get this to work, so I implement a cleaner way to have multiple posts buttons on one form instead of the single submit. You don’t wanna know what they’ve been doing so far.

5

Answers


  1. Chosen as BEST ANSWER

    I found the issue, it didn't had anything to do with the controller or the jQuery. Aparrently it only works when the Properties have actual getters & setters. Originally my viewmodel was written like:

    public class HomeViewModel
    {
        public string Id;
        public string UserFirstName;
        public string Language;
        public string __RequestVerificationToken;
        public List<DossierViewModel> Dossiers;
        ...
    }
    

    But it worked when written like this:

    public class HomeViewModel
    {
        public string Id { get; set; }
        public string UserFirstName { get; set; }
        public string Language { get; set; }
        public List<DossierViewModel> Dossiers { get; set; }
        ...
    }
    

    Thanks for everyone's help and effort.


  2. If you debug the controller you can use this.HttpContext in the immediate window to check what’s been passed though e.g.

    ?this.HttpContext.Request.Form
    or 
    ?this.HttpContext.Request.QueryString
    or
    ?new StreamReader(this.HttpContext.Request.Body).ReadToEndAsync().Result
    

    it’s likely the data doesn’t match the HomeModelView object, you could also add a bind to the controller action

    public IActionResult CurrentDossier([Bind("PropertyNameInModel,AnotherPropertyNameInModel") HomeViewModel model)
    

    I hope this helps

    Login or Signup to reply.
  3. I bet what you are looking for is to send the whole model thru AJAX post. In that case your data parameter of AJAX should look like:

     data: JSON.stringify(data);
    

    Json.Stringify() converts the object to JSON String and controller can recognize that JSON and will map your object properties to it

    Login or Signup to reply.
  4. you need to post antiforgerytoken validation since you have it in your action, add to ajax

     headers: {
                RequestVerificationToken:
    $('input:hidden[name="__RequestVerificationToken"]').val()
                    },
    

    or remove an antiforgerytoken validation from the action

    also redirect is not exist in a response, try

    ....
    if (data) {
                window.location.replace(data);
    }
    ....
    
    Login or Signup to reply.
  5. First you need to update your ajax data section by convert data to JSON string as shown below i .e.

    var jsonData = JSON.stringify(data);
    
    $.ajax({
       type: 'POST',
       url: url,
       contentType: 'application/x-www-form-urlencoded; charset=utf-8',
       data: jsonData ,
       success: function (data) {
        if (data.redirect) {
            window.location.replace(data.redirect);
         } else {
            $(dest).replaceWith(data);
         }
       },
       error: function (xhr, status, err) {
        //alert('Response code:' + xhr.status + 'rn[Error:' + err + '] ' + status);
       }
    });
    

    then in your controller action change the method parameter from HomeViewModel to string i.e.

    public IActionResult CurrentDossier(string data)
    

    Then inside that method convert JSON string to HomeViewModel i.e.

    public IActionResult CurrentDossier(string data)
    {
       HomeViewModel model = JsonConvert.DeserializeObject<HomeViewModel>(data);
    }
    

    Hope this helps

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search