ViVi ViVi - 28 days ago 21
C# Question

Posting entire model back to controller using ajax

I am a beginner in asp.net mvc and web technologies.
Now I am stuck at some point. I have a create user page. When admin user wants to add a new user, he is redirected to create user page with an empty data class. In that page, the data class is filled up. Now I want to return that model's data back to the controller using a POST method.

What I am trying to achieve is to directly post the entire model as a JSON object back to the controller and it is always null.

On create new user click :

[HttpGet]
public ActionResult CreateUser()
{
var newUser = new User();
return View(newUser);
}


My CreateUser View code :

@model WebApplication7.Models.User
@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>CreateUser</title>
<h2>Create new user</h2>
</head>
<body>
<div>
<table>
<tr>
<td>Username : </td>
<td>
@Html.TextBoxFor(model => model.userName, new { @class = "", id = "txtUsername", @maxlength = 6 })
</td>
</tr>

<tr>
<td>Password : </td>
<td>
@Html.TextBoxFor(model => model.passWord, new { @class = "", id = "txtUsername", @maxlength = 6 })
</td>
</tr>

<tr>
<td>First Name : </td>
<td>
@Html.TextBoxFor(model => model.firstName, new { @class = "", id = "txtUsername", @maxlength = 6 })
</td>
</tr>

<tr>
<td>Last Name : </td>
<td>
@Html.TextBoxFor(model => model.lastName, new { @class = "", id = "txtUsername", @maxlength = 6 })
</td>
</tr>

<tr>
<td>Display name : </td>
<td>
@Html.TextBoxFor(model => model.displayName, new { @class = "", id = "txtUsername", @maxlength = 6 })
</td>
</tr>

<tr>
<td>Email : </td>
<td>
@Html.TextBoxFor(model => model.emailID, new { @class = "", id = "txtUsername", @maxlength = 6 })
</td>
</tr>
<tr>
<td>
<input type="button" name="btnClear" value="Submit" class="btn-Clear" onclick="Submit()" />
</td>
</tr>
</table>
</div>
</body>
</html>


The Submit function code :

<script>
function Submit() {
$.ajax({
type: "POST",
url: "/UserManagement/SubmitNewUserData",
data: JSON.stringify({ userData: model }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
ServiceSucceeded(msg);
},
error: function () {
return "error";
}
});
}
</script>


My Controller Code :

[HttpPost]
public JsonResult SubmitNewUserData(User userData)
{
if (userData != null)
{

}
return Json(true);
}


The
userData
here is null always. Please help me to post back that model to this controller. Thank you.

Answer

You have not indicated what the value of model is, but in order to work, it would need to

var model = {
    userName: $('#userName').val(),
    passWord: $('#passWord').val(),
    ... // etc for each property of User
};

assuming you remove all you new { id = "txtUsername" } attributes which is generating invalid (duplicate) name attributes.

A far easier solution is to wrap all you form controls in a <form> tag and then use .serialize(); to correctly serialize all your form controls. The script would then be

$.ajax({
    type: "POST",
    url: '@Url.Action("SubmitNewUserData", "UserManagement")', // always use Url.Action() to generate your url's
    data: $('form').serialize;
    dataType: "json",
    success: function (msg) {
        ServiceSucceeded(msg);
    },
    error: function () {
        return "error";
    }
});
return false; // cancel the default submit

To improve this further, remove your onclick="Submit()" and handle the .submit() event using Unobtrusive Javascript

$('form').submit(function() {
    if (!$(this).valid()) {
        return;
    }
    $.ajax({
       ....
    });
    return false;
});

The if (!$(this).valid()) { will allow you to handle client side validation, which you should be doing by including @Html.ValidationMessageFor(..) helpers and including the relevant jquery.validate.js and jquery.validate.unobtrusive.js scripts, and adding validation attributes to your model properties so that you get both client and server side validation.

Side note: A password field should be generate with @Html.PasswordFor(). Its also unclear why your using ajax rather than a standard submit (why would you want the user to stay on the same page and edit it again?