Saving JSON received through a controller to the database MVC - c#

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

Related

Post action in ASP.NET MVC always receives null

I have read a lot of questions regarding similar issues, but none of them seems to work for me.
I am receiving null for the movie object in the post action method.
This is my controller:
public class MovieController : Controller
{
[Route("movies/all")]
[HttpGet]
public ActionResult All()
{
List<string> movies = new List<string>();
movies.Add("Some Movie");
movies.Add("Diamond Team");
//Get movies
return Ok(movies);
}
[Route("movies/post")]
[HttpPost]
public ActionResult Post([FromBody] Movie movie)
{
Console.WriteLine(movie);
List<string> movies = new List<string>();
movies.Add(movie.title);
//Get movies
return Ok(movies);
}
public ActionResult Index()
{
return View();
}
}
This is the Movies class:
public class Movie
{
public string title { get; set; }
public float rating { get; set; }
public int year { get; set; }
public Movie(string title,float rating, int year)
{
this.title = title;
this.rating = rating;
this.year = year;
}
public Movie()
{
}
}
This is the post request (using postman), I have tried either application/json and application/json; charset=utf-8 as the Content-Type but in both cases I have received null for the movie object:
{
"title":"Some Movie",
"rating":"1.87",
"year":"2011"
}
Postman screenshots:
How can I fix this?
Please try to change your request JSON to this:
{
"title":"Some Movie",
"rating":1.87,
"year":2011
}
Your model must first be serialized and then passed to data in ajax call. this is one sample, You have to change the model according to your needs....
$("#btnPost").click(function() {
var employee = new Object();
employee.Name = $('#txtName').val();
employee.Address = $('#txtDesignation').val();
employee.Location = $('#txtLocation').val();
if (employee != null) {
$.ajax({
type: "POST",
url: "/JQueryAjaxCall/AjaxPostCall",
data: JSON.stringify(employee),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
if (response != null) {
alert("Name : " + response.Name + ", Designation : " + response.Designation + ", Location :" + response.Location);
} else {
alert("Something went wrong");
}
},
failure: function(response) {
alert(response.responseText);
},
error: function(response) {
alert(response.responseText);
}
});
}
});
in the postman you can use different way to call method. Click on code button and choose one of way to call method.
you can use jquery and put code onto section....

POST to MVC controller is NULL from KnockoutJS

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

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

Webapi parameter is null on Method

I'm trying to post back a list of data objects (WorkOrders), in JSON format to my Webapi controller, this works amazingly well, except for the slight flaw in that the data object parameter (savemodel) is null when it hits the webapi controller.
This is a snip from the JS (slots is mock data)
var slots = [];
slots.push({ 'WorkOrder': 'XX21', 'OrderDate': '2015-10-11 00:00:00', 'Slot': '1', 'SageRef': 'HS11' });
slots.push({ 'WorkOrder': 'XX22', 'OrderDate': '2015-10-12 00:00:00', 'Slot': '2', 'SageRef': 'HS12' })
slots.push({ 'WorkOrder': 'XX23', 'OrderDate': '2015-10-13 00:00:00', 'Slot': '3', 'SageRef': 'HS13' });
console.log(JSON.stringify({ 'savemodel': slots }))
$.ajax({
type: "POST",
url: 'http://localhost:55821/api/schedule',
data: JSON.stringify({ 'savemodel': slots }),
contentType: 'application/json; charset=utf-8'
}).success(function (data) {
$scope.$apply(function () {
if (data.SaveMessage.length > 0) {
// do something
}
else {
// do something else
}
});
});
The model:
public class WorkOrderModel
{
public string WorkOrder { get; set; }
public string OrderDate { get; set; }
public string SlotNumber { get; set; }
public string SageRef { get; set; }
}
The postback method:
[HttpPost]
public IHttpActionResult UpdateWorkOrder([FromBody]List<WorkOrderModel> savemodel)
{
StringBuilder saveMessage = new StringBuilder();
foreach (WorkOrderModel model in savemodel)
{
// save the WO model object here
}
if (saveMessage.Length > 0)
{
return Ok(new { SaveMessage = "There were issues: " + saveMessage.ToString() });
}
else
{
return Ok(new { SaveMessage = "" });
}
}
Posted JSON
Null parameter in the WebApi Controller
This is driving me nuts so any help will be hugely appreciated at this stage!
Regards,
itsdanny
Sorted, it changed
data: JSON.stringify({ 'savemodel': slots}),
to
data: JSON.stringify(slots),

Return JsonResult with List of objects from MVC controller

I have a simple method in my MVC controller:
[HttpPost]
public JsonResult GetAreasForCompany(int companyId)
{
var areas = context.Areas.Where(x => x.Company.CompanyId == companyId).ToList();
return Json(areas);
}
This is an area object:
public class Area
{
public int AreaId { get; set; }
[Required]
public string Title { get; set; }
public bool Archive { get; set; }
public virtual Company Company { get; set; }
}
And this is how I call the method from the view:
$.ajax({
url: '#Url.Action("GetAreasForCompany")',
type: 'POST',
async: false,
data: "{'companyId': " + companyId + "}",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
error: function () {
alert("Server access failure!");
},
success: function (result) {
response = result;
}
});
I have checked the method in the controller and a list of Area objects gets created. Would you have any idea why do I get the 500 internal server error when the method is called from the view? When I return anything else (like a Dictionary object) everything works fine, it's just when I aim to convert the List of Areas into Json I get an error.
Since class Area contains Company and Company contains collection of Area you likely have circular references in your object hierarchy which is not supported by the JSON serializer. To solve this, return anonymous objects with only those properties you need, for example
[HttpPost]
public JsonResult GetAreasForCompany(int companyId)
{
var areas = context.Areas
.Where(x => x.Company.CompanyId == companyId)
.Select(a => new
{
AreaId = a.AreaId,
Title = a.Title
});
return Json(areas);
}
Return List Object as Json (Also useful for JqueryUI and Linq Method)
public ActionResult GetItemList()
{
var search = Request.Params["term"];
var itemList = (from items in db.TblItems where items.ItemName.StartsWith(search) select new { label = items.ItemName, value = items.ItemName }).ToList();
return Json(itemList, JsonRequestBehavior.AllowGet);
}

Categories

Resources