Reputation: 19
It looks like this has been talked to death, but I still can't seem to get my code to work.
I'm attempting to use Knockoutjs's editable table and use an AJAX post to a controller to add to the model. However, the post is always null in the controller.
Here's the model:
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
namespace Adder_Web.Models
{
public class User
{
[Display(Name = "ID")]
[Required]
[StringLength(9, ErrorMessage = "SSO must be 9 numbers", MinimumLength = 9)]
public virtual string ID { get; set; }
[Display(Name = "First Name")]
[Required]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
[Required]
public string LastName { get; set; }
}
public class UserContext : DbContext
{
public DbSet<User> Users { get; set; }
}
}
Here's the controller I'm attempting to post to. The users is null when posted to:
[HttpPost]
public async Task<ActionResult> CreateMultiple(IEnumerable<User> users)
{
if (ModelState.IsValid)
{
foreach (User oneUser in users)
{
db.Users.Add(oneUser);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
}
return View(users);
}
And here's the javascript:
script>
var UserModel = function (users) {
var self = this;
self.users = ko.observableArray(users);
self.addUser = function () {
self.users.push({
id: "",
firstName: "",
lastName: ""
});
};
self.removeUser = function (user) {
self.users.remove(user);
};
self.save = function (form) {
sendData = JSON.stringify(self.users);
$.ajax({
url: '/Users/CreateMultiple',
contentType: "string",
async: true,
type: "POST",
data: JSON.stringify(sendData),
error: function (jqXHR, textStatus, errorThrown) {
console.log("FAIL: " + errorThrown);
},
success: function (data, textStatus, jqXHR) {
console.log("SUCCES");
}
});
};
};
var viewModel = new UserModel([
{ id: "123456789", firstName: "John", lastName: "Doe" }
]);
ko.applyBindings(viewModel);
// Activate jQuery Validation
$("form").validate({ submitHandler: viewModel.save });
</script>
Upvotes: 0
Views: 684
Reputation: 199
@rStackSharper
Just make it sure that your user models on the back end and on the front end have identical properties.
Example:
on your back end,
class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
on your front end should be,
var user = { FirstName: "John", LastName: "Doe" };
or if you create a function to it;
function user(){
this.FirstName = "John";
this.LastName = "Doe";
}
then when you send it to the server you have to JSON.stringify(user) for it to be accepted
Upvotes: 0
Reputation: 19
I was able to get it sorted by making the following changes:
AJAX:
self.save = function (form) {
sendData = ko.toJSON(self.users);
$.ajax({
url: '/Users/CreateMultiple',
contentType: 'application/json',
async: true,
type: 'POST',
dataType: 'json',
data: sendData,
error: function (jqXHR, textStatus, errorThrown) {
console.log("FAIL: " + errorThrown);
},
success: function (data, textStatus, jqXHR) {
console.log("SUCCES");
}
});
};
CONTROLLER:
[HttpPost]
public ActionResult CreateMultiple(List<User> users)
{
if (ModelState.IsValid)
{
foreach (User oneUser in users)
{
db.Users.Add(oneUser);
db.SaveChanges();
}
return RedirectToAction("Index");
}
return View();
}
Upvotes: 0
Reputation: 110
do changes to your ajax method as below it might be help you. Thank You
or else Simply change ajax method data attribute like ex:- data: JSON.stringify(sendData) to data: ({users:sendData}),
Note:- users in 'data:({users:sendData})' is your CreateMultiple(IEnumerable users) method parameter name
$.ajax({
url:'@Url.Content("~/Users/CreateMultiple")',
async: true,
cache:false,
type: 'POST',
data: ({users:sendData}),
error: function (jqXHR, textStatus, errorThrown) {
console.log("FAIL: " + errorThrown);
},
success: function (data, textStatus, jqXHR) {
console.log("SUCCES");
}
});
Upvotes: 0
Reputation: 101
Can you try to remove Content-Type and stringfy, i hope it wil work and if your ajax method is post with an object, you dont have to put [FromBody] attribute. You can use this attribute like following.
[HttpPost]
public async Task<IActionResult> CreateMultiple([FromBody] string userCode){
}
[HttpGet]
public async Task<IActionResult> CreateMultiple(string userCode){
}
Upvotes: 0
Reputation: 2222
Javascript Part:
sendData
two times application/json
)C# Part:
In your Controller you have to inform your Method that the Model comes from the body of your http post request.
public async Task<IActionResult> CreateMultiple([FromBody] IEnumerable<User> users)
{
/*..*/
}
Upvotes: 1