'Model binding with jquery ajax serialize not working

I have the following model:

public class RegisterUseraccount
{
    [Required]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "E-Mail-Adresse")]
    public string Email { get; set; }

    [Required]
    [Display(Name = "Vorname")]
    public string FirstName { get; set; }

    [Required]
    [Display(Name = "Nachname")]
    public string LastName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [MinLength(5)]
    [Display(Name = "Passwort")]
    public string Password { get; set; }

    ...
}

And the following view:

@using (Html.BeginForm("Register", "Useraccount", FormMethod.Post, new { id = "registerUseraccountForm", @class = "ym-form" }))
{
    @Html.ValidationSummary(true)        

    <div class="ym-grid">
        <div class="ym-g50 ym-gl">
            <div class="ym-fbox-text">
                @Html.LabelForRequired(model => model.RegisterUseraccount.FirstName, null)               
                @Html.EditorFor(model => model.RegisterUseraccount.FirstName, new { required = "required", name = "firstName" })
                @Html.ValidationMessageFor(model => model.RegisterUseraccount.FirstName)                  
            </div>
        </div>
    ...

and my JavaScript

function sendForm(target) {
    alert(data);
    $.ajax({
        url: target,
        type: "POST",
        contentType: 'application/json',
        data: $("#registerUseraccountForm").serialize(),
        success: ajaxOnSuccess,
        error: function (jqXHR, exception) {
            alert('Error message.');
        }
    });

This is the result of the serialization:

RegisterUseraccount.FirstName=Peter&RegisterUseraccount.LastName=Miller&RegisterUseraccount.Email=miller%40gmail.com&RegisterUseraccount.Password=admin

This is my controller method I'm trying to POST to:

[HttpPost]
public ActionResult Register(RegisterUseraccount registerUseraccount)
{
    ...
}

... but the data doesn't arrive at the method, I get an error 404. I think the modelbinder can't work.

What works is data which is sent with the name firstName=Peter, but what actually is sent is RegisterUseraccount.FirstName=Peter.

How can I handle this problem?



Solution 1:[1]

Maybe you have this model

public class YourModel
{
    public RegisterUseraccount RegisterUseraccount { get; set; }
}

In this case you have to put the model that corresponds to your action:

[HttpPost]
public ActionResult Register(YourModel model)
{
    var registerUseraccount = model.RegisterUseraccount;
    ...
}

Or:

@using (Html.BeginForm("Register", "Useraccount", FormMethod.Post, new { id = "registerUseraccountForm", @class = "ym-form" }))
{
   @{ Html.RenderPartial("RegisterUseraccount"); }
}

RegisterUseraccount.cshtml

@model YourNamespace.RegisterUseraccount

@Html.ValidationSummary(true)        

<div class="ym-grid">
    <div class="ym-g50 ym-gl">
        <div class="ym-fbox-text">
            @Html.LabelForRequired(model => model.FirstName, null)               
            @Html.EditorFor(model => model.FirstName, new { required = "required", name = "firstName" })
            @Html.ValidationMessageFor(model => model.FirstName)                  
        </div>
    </div>

but you'll have to change some things like @Html.ValidationSummary (true).

Edit

or most simple:

data: $("#registerUseraccountForm").serialize().replace("RegisterUseraccount.",""),

Edit II

data: $("#registerUseraccountForm").serialize().replace(/RegisterUseraccount./g,""),

Solution 2:[2]

There are two variations of posting data with jQuery ajax.

  1. Use $.ajax
  2. Use $.post

Below shows how to use $.post

   $('#btn-register').click(function () {

        var $form = $('#registerUseraccountForm');

         if ($form.valid()) {
        
               var url = $form.attr('action'),
                   fd = $form.serialize();
    
                $.post(url, fd).done(function (result) {
                    if (result) {
                        Swal.fire(
                            'Success!',
                            'User registered successfully',
                            'success'
                        )
                    } else
                        Swal.fire(
                            'Failed!',
                            'Failed to register user',
                            'error'
                        )
                }).fail(function () {
                    Swal.fire(
                        'Failed!',
                        'Failed to register user',
                        'error'
                    )
                });
            }else{
                Swal.fire(
                    'Invalid!',
                    'Form contains invalid data',
                    'error'
                )
            }
        });

I would say in such places where you don't require to do additional configurations as you do with $.ajax, simply serialize the form and just post. Of course, validate the form if you already defined validations for fields. Pretty straightforward!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Peck_conyon