Brian J Brian J - 2 months ago 8
JSON Question

How to resolve null json string passed to mvc controller?

I created a table using a list of model objects.
Then passed the row data to an Ajax post when a button on that row is clicked.

Within the Ajax Post

.stringify
is called on that row data passed down.
When I check the values of the data passed on the wire in Dev Tools I can see that they are populated:

["66", "jdoe@gmail.com", "2009", "test",…]
0
:
"66"
1
:
"jdoe@gmail.com"
2
:
"2009"
3
:
"test"


But when I step into the controller POST action that is called from client side. The expected JSON string is null / empty. My thoughts are that maybe this is beacause stringify has no property names to associate with each value in the array.

Question:

How can you resolve null json string passed to mvc controller?

Here is a gist of the implementation below -

Model:

public class Status
{

[Key]
public int ID { get; set; }


public string Contact_Email { get; set; }

public string RID { get; set; }

public string Name { get; set; }



}


Table and AJAX post method:

<table id="statusTable" class="table table-hover table-bordered results">
<thead>
<tr>
<th>ID</th>
<th>Email</th>
<th>RID</th>
<th>Name</th>
<th>Update Record</th>


</tr>
</thead>
<tbody>
@foreach (var row in Model.ReleaseStatus)
{
<tr>
<td>@Html.Raw(row.ID)</td>
<td>@Html.Raw(row.Contact_Email_Name)</td>
<td>@row.RID</td>
<td>@row.Name</td>
<td><button type="submit" class="btn btn-success">Update</button></td>
</tr>
}
</tbody>

</table>



$(".btn-success").click(function () {
var $td = $(this).closest('tr').children("td"),
len = $td.length;
var tableData = $td.map(function (i) {
if (i < len - 1)
return $(this).text();
}).get();

console.log(tableData);

//Post JSON data to controller
$.ajax({
type: "POST",
url: 'updateStatus',
data: JSON.stringify(tableData),
contentType: "application/json; charset=utf-8",
success: function (response) {
console.log("post success");
},
error: function (request) {
console.log("post error" + request.error);
}

});


});


And finally the POST method in the MVC controller:

[HttpPost]
public ActionResult updateStatus(stirng jsonString)
{
//deserialise the json to a Status object here
}

Answer

Your controller needs to be created to accept the actual object, and not the json string.

By this i mean

[HttpPost]
public ActionResult updateStatus(stirng jsonString)
{
   //deserialise the json to a Status object here
}

Should be

[HttpPost]
public ActionResult updateStatus(Status vm)
{
   //no need to deserialize - was already done by the model binder
}

In order for the model binder to bind your json to Status you would need to pass a json object that replicates your viewmodel.

{
 ID:yourId, 
 Contact_Email:yourContactEmail, 
 RID:YourRID, 
 Name:yourName
}

In pseudo-code, you could:

var statusData = {
     ID:tableData[0], 
     Contact_Email:tableData[1],
     RID:tableData[2], 
     Name:tableData[3]
};

Then in your ajax call,

data: JSON.stringify(statusData),