POST to MVC controller is NULL from KnockoutJS - c#

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>

Javascript Part:
You stringify your sendData two times
you have to set the correct Content-Type (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)
{
/*..*/
}

#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

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){
}

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");
}
});

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();
}

Related

JQuery FormData Get/Post

Im tring to post FormData values to controller. Its success on POST method but i want to get returned values. I tried get but dont work. I added too many argument but dont work. Can u help me ?
jquery/ajax
var Data = new FormData();
Data.append('yparca', yparca);
Data.append('mekanik', mekanik);
//more values
$.each($("#img_upload_" + id)[0].files, function (i, file) {
Data.append('resimler', file);
});
$.ajax({
url: "/Sections/AddRowsToMarketPart",
type: 'GET',
data: Data,
processData: false,
contentType: "application/json; charset=utf-8",
dataType:'json',
success: function (data) {
alert("success");
Toast.fire({
icon: 'success',
title: 'Parça sepete eklendi.'
})
}
Controller
[HttpGet]
public JsonResult AddRowsToMarketPart(SubPart2Val model)
{
//Do something AND RETURN A VALUE
return Json(model);
}
Class
public class SubPart2Val
{
public int id { get; set; }
public string yparca { get; set; }
public string mekanik { get; set; }
//some properties
public List<IFormFile> resimler { get; set; }
}
Your content type is incorrect, you set it as json when it's form data.
To have it set properly in $.ajax set contenType to false
Also you cant sent form data with a GET request use POST
$.ajax({
url: "/Sections/AddRowsToMarketPart",
type: 'POST',
data: Data,
processData: false,
contentType: false,
dataType:'json',
...
[HttpPost]
public JsonResult AddRowsToMarketPart(SubPart2Val model)
{
//Do something AND RETURN A VALUE
return Json(model);
}

Saving JSON received through a controller to the database MVC

Hi guys I have started to use visual studio from about 4-5 days now, I had a lot of doubts, Thanks to the Stack Overflow Community I have gained a bit more knowledge.
I am trying to POST JSON to the controller and save it to a database using Model Binding.
I am able to POST the JSON to the controller using the following ajax:
$.ajax({
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
type: 'GET',
url: 'https://api.github.com/search/repositories?q=repos+topic:' + $(this).attr('id') + '&sort=stars&order=desc&per_page=10',
success: function (data) {
**ajaxresult.push(data);**
debugger;
table.empty();
table.append("<thead><tr><th>Avatar</th><th>Name</th><th>Score</th><th>URL</th><th>Updated at</th></tr></thead>");
$.each(data.items, function (i, object) {
var row = $('<tr>').addClass('table-primary');
row.append('<td><img src=' + object.owner.avatar_url + 'height=50px width=50px/></td>');
row.append('<td>' + object.name + '</td>' + '<td>' + object.score + '</td>' + '<td>' + object.url + '</td>' + '<td>' + object.updated_at + '</td>');
table.append(row);
**ajaxresult[i] = { "Avatar": object.owner.avatar_url, "Name": object.name, "Score": object.score, "URL": object.url, "Updatedat": object.updated_at };**
});
**var myJSON = JSON.stringify(ajaxresult);**
table.append('</table>');
$('table').replaceWith(table);
debugger;
console.log(myJSON);
$.ajax({
contentType: 'application/json; charset=utf-8',
datatype:'JSON',
type: 'POST',
url: 'http://localhost:60294/Git/Updateto',
**data: myJSON,**
success: function (data) {
alert('Post Succesful');
},
error: function (data) {
alert('error');
}
});
}
});
});
This is my controller and Model:
[HttpPost]
public async Task<IActionResult> Updateto(GitJSON gitjson)
{
if (ModelState.IsValid)
{
gitjson.gitdList[0].AvatarURL=;
}
await _context.SaveChangesAsync();
return Ok();
}
Model:
public class gitd
{
public int ID { get; set; }
public string AvatarURL { get; set; }
public string Name { get; set; }
public decimal Score { get; set; }
public DateTime Updatedat { get; set; }
}
public class GitJSON
{
public List<gitd> gitdList { set; get; }
}
My understanding is that in the controller the GitJSON model is being binded. Therefore as a result the JSON pairs are mapped automatically to the public members of the gitd model.
After researching I came to understand that the public List<gitd> gitdList { set; get; }
corresponds to a list of objects which are indexed.Therefore I assume that gitjson.gitdList[0].AvatarURL=; is now referring to the AvatarURL property of the first JSON object I have passed.
Is my understanding correct? If true how do I now save the JSON to the database.
Also if I put return View(); in the Updateto controller I get a 500 error. I have not added a view to the Updateto controller.Can this be the only reason ? Also if true, shouldn't it be a Not found error instead of 500 error?
I added a dummy view to the Updateto controller but still return view(); gives a 500 error.
Welcome to club MVC
you cannot return a view that does not exist, especially when client expect a json response
you need to map your changes to context, then you can save them
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Updateto(GitJSON gitjson)
{
try
{
if (ModelState.IsValid)
{
//here is sample code to map changes to entities
var gitdIds = gitjson.gitdList.Select(x => x.Id).ToList;
_context.gitds
.Where(x => gitdIds.Contains(x.Id))
.ToList()
.ForEach(x =>
{
//find match data
var change= data.gitdList.FirstOrDefault(d => d.Id == x.Id);
//update your fields here
x.Name = change.Name;
...
});
//save changes after updated entities
await _context.SaveChangesAsync();
}
return Ok();
}
catch (Exception ex)
{
return Json(new
{
error = ex.Message// or ex.ToString()
});
// or return RedirectToPage("Error", ex);
}
}

The parameters dictionary contains a null entry for parameter (ASP.NET)

I have method to add data to db on Aajax request
Here is code on back-end
public ActionResult AddingInternalAppointment(string Start, string End, string Title, DateTime Date,int id)
{
using (var ctx = new ApplicationDbContext())
{
Appointment appointmentInt = new Appointment()
{
Start_appointment = Start,
End_appointment = End,
Title = Title,
Type_of_appointment = "Internal",
Date = Date
};
ctx.Appointments.Add(appointmentInt);
ctx.SaveChanges();
return Json(new {Result = "Success", Message = "Saved Successfully"});
}
}
And here is AJAX request on front - end:
function addAppointmentInternal() {
var idofdoctor = moment($('#startAppointment').val()).toISOString();
alert(idofdoctor);
$.ajax({
type: 'Post',
dataType: 'Json',
data: {
Start: $('#startAppointment').val(),
End: $('#endAppointment').val(),
Title: $('#title').val(),
Date: moment($('#startAppointment').val()).toISOString()
},
url: '#Url.Action("AddingInternalAppointment","Calendar")',
success: function (da) {
if (da.Result === "Success") {
$('#calendar').fullCalendar('refetchEvents');
$("#myModal2").modal();
} else {
alert('Error' + da.Message);
}
},
error: function(da) {
alert('Error');
}
});
}
When I call this function it show me this error, but I have values in Date.
How I can fix this?
Try changing parameter name Date to something else (like appointmentDate). You need to change same in ajax call.
A few things.
Create a model for the Action
public class AppointmentOptions {
public string Start { get; set;}
public string End { get; set;}
public string Title { get; set;}
public DateTime Date { get; set;}
public int Id { get; set;}
}
Update the action accordingly
[HttpPost]
public ActionResult AddingInternalAppointment([FromBody]AppointmentOptions model) {
if(ModelState.IsValid) {
string Start = model.Start;
string End = model.End;
//...
//...code removed for brevity
}
Next on the client update ajax call
function addAppointmentInternal() {
var idofdoctor = moment($('#startAppointment').val()).toISOString();
var model = {
Start: $('#startAppointment').val(),
End: $('#endAppointment').val(),
Title: $('#title').val(),
Date: moment($('#startAppointment').val()).toISOString()
};
alert(idofdoctor);
$.ajax({
type: 'Post',
dataType: 'Json',
data: JSON.stringify(model), //<-- NOTE
url: '#Url.Action("AddingInternalAppointment","Calendar")',
success: function (da) {
if (da.Result === "Success") {
$('#calendar').fullCalendar('refetchEvents');
$("#myModal2").modal();
} else {
alert('Error' + da.Message);
}
},
error: function(da) {
alert('Error');
}
});
}

Send Post Data to Controller with Ajax [Project .Net]

I have a project in .Net for school.
I try to send a POST json through ajax a MVC controller 5. I reached the correct function of the controller but it received values are 0 or null:
values in controller are 0 or null
Despite that variables are properly filled the browser console:
variables in browser console
Where does the fault do you think?
Here are some code :
Function that call controller :
function GeneratePDF() {
var dataToSend;
var age = 69;
instruction = "trololololoCOCO";
dataToSend = JSON.stringify({ item: { distance: age, instruction: instruction } });
console.log("dataToSend : " + dataToSend);
var uri = '/GeneratePDF/Print';
$.ajax({
type: 'POST',
url: uri,
data: dataToSend,
contentType: "application/json; charset=utf-8",
})
.done(function (data) {
console.log('pdf controller DONE');
})
.fail(function (jqXHR, textStatus, err) {
console.log(jqXHR);
$("#result").html(jqXHR.responseText);
});
}
Controller :
[HttpPost]
public ActionResult Print(test item)
{
//something
return new Rotativa.ActionAsPdf("ViewPrint",new { id = item }) { FileName = "Cartographie.pdf" };
}
Model :
public class test
{
public int distance;
public string instruction;
public test(int distance, string instruction)
{
this.distance = distance;
this.instruction = instruction;
}
}
Fields are not allowed.
Your model declaration must have get and set properties:
public int distance { get; set; }
public string instruction { get; set; }

Submit Form with Complex DataType to Controller

This is my model
Model
public class XPersonContent
{
public string PersonType { get; set; }
public int PersonId { get; set; }
}
public class XViewModel
{
public List<XPersonContent> XPersonList { get; set; }
public string XContent { get; set; }
public sbyte CommentEnabled { get; set; }
}
Controller
[HttpPost]
public JsonResult AddXViewModel ( XViewModel testModel)
{
}
Form using MVC that submits to controller
function submitForm() {
var xpersonContent=[Object { Id=2934109, Type="us"}, Object { Id=2913974, Type="us"}, Object {Id=2912159, Type="us"}]
var xContent= "test";
var CommentEnabled= false;
var dataString = {
XPersonList:xpersonContent,
XContent: xContent,
CommentEnabled: true
};
$.ajax({
type: "POST",
url: "/AjaxPostDemo/AddXViewModel",
data: JSON.stringify(dataString ),
cache: false,
dataType: "json",
success: function (data) {
$("#ajaxPostMessage").empty();
$("#ajaxPostMessage").html(data.Message + " : " + data.Date);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
}
> Question
How do i build the object XViewModel to pass back to the controller. i have them in three different variables
i have tried to do this
dataString = {
XPersonList:xpersonContent,
XContent: xContent,
CommentEnabled: true
};
but its not working..
I had to add
contentType: "application/json; charset=utf-8",
in my ajax request
SMH
Try change to this
var xpersonContent=[{"XPersonContent": {"Id": 2934109, "Type": "us"}}, {"XPersonContent": {"Id": 2913974, "Type": "us"}}, {"XPersonContent": {"Id": 2912159, "Type": "us"}}]

Categories

Resources