Posting JSON to controller MVC 5 - json

I am posting JSON to my controller, but the problem is I am getting the correct count in list. i.e if JSON has two elements list has count of two but null data. Following is the code via I am making and sending the JSON. I've use TabletoJSON for making the JSON.
$('#productsObj').click(function () {
var rawMaterials = $('#productsTable').tableToJSON(
{
ignoreColumns: [3]
});
alert(JSON.stringify(rawMaterials));
console.log(rawMaterials);
$.ajax({
url: "/Supplies/insertRawMaterial",
type: "POST",
data: JSON.stringify(rawMaterials),
contentType: "application/json; charset=utf-8",
dataType: "json",
traditional: true,
error: function (response) {
alert(response.responseText);
},
success: function (response) {
alert(data);
alert(response);
}
});
});
Following is the controller action method which is receiving data.
public ActionResult insertRawMaterial(List<String> data)
{
if (data != null)
{
return Json("Success");
}
else
{
return Json("An Error Has occoured");
}
}
I am not sure where I am doing it wrong. Following is the JSON in alert.
[{"Raw Material Name":"Asphalt","Short Code":"AS02","Price":"20"}]

You cannot possibly expect to map this complex JSON structure to a list of strings (List<String>) that your controller action currently takes as parameter:
[{"Raw Material Name":"Asphalt","Short Code":"AS02","Price":"20"}]
So you may start by defining the appropriate view models that will reflect this structure (or almost, see the massaging technique required below):
public class MaterialViewModel
{
public string Name { get; set; }
public string ShortCode { get; set; }
public decimal Price { get; set; }
}
which your controller action will take as parameter:
public ActionResult insertRawMaterial(IList<MaterialViewModel> data)
{
...
}
and finally massage your data on the client to match the correct property names (name, shortCode and price of course):
// we need to massage the raw data as it is crap with property names
// containing spaces and galaxies and stuff
var massagedRawMaterials = [];
for (var i = 0; i < rawMaterials.length; i++) {
var material = rawMaterials[i];
massagedRawMaterials.push({
name: material['Raw Material Name'],
shortCode: material['Short Code'],
price: material['Price']
});
}
$.ajax({
url: "/Supplies/insertRawMaterial",
type: "POST",
data: JSON.stringify(massagedRawMaterials),
contentType: "application/json; charset=utf-8",
...
This being said, if the client side library you are currently using produces such undeterministic property names, you might consider replacing it with something more appropriate.

Related

ajax doesn't pass array of objects to action

I am using ajax to pass Json data to an action in an asp.net core project.
I have an array of objects to pass
var AgentScores = [];
.
.
.
AgentScores.push({
AgentId: AgentId,
Fullname: Fullname,
Score : Score
});
$.ajax({
type: "POST",
url: "/Score/SelfReportedScores",
contentType: 'application/json; charset=utf-8',
//large data must be passed using json
data: JSON.stringify(AgentScores),
success: function (result) {
},
error: function (e) {
}
});
I have a class called AgentsListScoreClass.cs and below is how I am trying to get the array in my action:
public void SelfReportedScores([FromBody] List<AgentsListScoreClass> AgentScores)
{
AgentScores is always null.
It is ok when I pass a List of string, but with AgentsListScoreClass it is always null.
public class AgentsListScoreClass
{
public string AgentId { get; set; }
public string Fullname { get; set; }
public short Score { get; set; }
}
AgentScores is always null.
Please capture the actual request with posted data in browser developer tool Network tab, and check if the data you posted look like below.
And the property AgentId of your AgentsListScoreClass model is defined as string type, please make sure you wrap the value with quotes, like this "AgentId":"1".
Update:
AgentScores.push({AgentId: AgentId, Fullname: Fullname, Score : Score});
this is how data looks like 'data = "[{"AgentId":"015d6fce-2b6e-4702-b4ac-8af31bba8ffa","Fullname":"name","Score":"0"},{"AgentId":" ......'
You can try to use parseFloat() function to parse Score data, like below.
AgentScores.push({
AgentId: AgentId,
Fullname: Fullname,
Score: parseFloat(Score)
});
you have to fix ajax bugs by removing contenttype and stringify
var agentScores = [];
agentScores.push(
{
AgentId: AgentId,
Fullname: Fullname,
Score : Score
}
);
$.ajax({
type: "POST",
url: "/Score/SelfReportedScores",
data: { agentScores },
success: function (result) {
},
error: function (e) {
}
});
And maybe you need [FromBody] only for a Postman. Try to remove it if you still have null.

How to retrieve JSON data in controller in ASP.net Core?

i need to get data sent with JSON and save to model in asp.net controller
//JSON data
var dataType = 'application/json';
var data = {
ID: 'Zaki',
}
console.log('Submitting form...');
console.log(data);
$.ajax({
type: 'POST',
url: 'Save',
dataType: 'json',
contentType: dataType,
data: data,
success: function (result) {
console.log('Data received: ');
console.log(result);
}
});
Controller
[HttpPost]
public ActionResult Save([FromBody] string ID)
{
return Json (ID);
}
am getting null in console , it supposed to be zaki and from there i wanna write saving code...
Another way to do it is to simply use 'dynamic' type to handle json request data. Take a look:
[HttpPost]
public IActionResult YoutMethod([FromBody] dynamic requestData)
{
Log.Information(requestData.field1);
Log.Information(requestData.field2);
// ...
return Ok();
}
Modify this line in your code data: data, to
data:JSON.stringify(data)
When sending data to a web server, the data has to be a string and JSON.stringify method converts a JavaScript object into a string.
Another approach would be, instead of getting raw string value, wrap your parameter into a class object like this
public class ParamObj
{
public string ID{get;set;}
}
and in your controller get a parameter of this object type like this..
public ActionResult Save([FromBody] ParamObj data)
Thanx
I know that is already marked as answered, but here is another way to do it:
I am not using the binding FromBody attribute.
Controller
public class JsonRequest
{
public string Id { get; set; }
}
[HttpPost]
public ActionResult Save(JsonRequest data)
{
return Json(data.Id);
}
Instead of using dataType I am using accept and you don't need to convert your json into a string.
To avoid problems with relative paths I am using: url: '#Url.Action("Save", "Home")' as well.
Javascript
function send()
{
//JSON data
var dataType = 'application/json';
var data = {
"id": "Zaki"
}
console.log('Submitting form...');
console.log(data);
$.ajax({
type: 'POST',
url: '#Url.Action("Save", "Home")',
accept: dataType,
data: data,
success: function (result) {
console.log('Data received: ');
console.log(result);
}
});
}
Good luck with your project.

How to pass a collection of <Model> from view to Controller in .net mvc

thanks for taking the time to read my question....
The solution doesn't have to be with ajax ... i need anything to make this work as described....
I need to do the following
Image for the site
if i select private cars from the ad type it shows only the private cars, if i select BMW Make it shows only BMW , and so on for the rest of the search... i did that ..
The problem is when i try to combine multiple searches parameters
example: if i need to show only the private Used cars which are BMW and in specific city and sort the result by price or mileage etc....
I didn't manage to do that ... i tried to wrap the results every time as a list then pass this list by ajax to a controller to do the stuff then retrieve it in a partial View... but i couldn't pass This list (list(Class UserCar))......
I think that if a generous man guided me to do sorting right , it will be same for all search parameters...
This is the view model which contains usercar Model which have all the data i want to retrieve from database
public class VMUserCar
{
public UserCar UserCar { get; set; }
public IEnumerable<UserCar> CarsList { get; set; }
public int? CarsListCount{ get { return CarsList.Count(); } }
}
This is the Index which contains the partial View
<div class="searchDiv">
#Html.Partial("~/Views/Partial_Views/_DisplayAds/_SearchResultDisplay.cshtml")
</div>
This is the partial view which displays all the userCars which displayed in the site image above ( I removed html as possible to minimize distractions)
#model CarSales.Models.CarsForSale.VMUserCar
#foreach (var item in Model.CarsList)
{
#item.Year #item.Make #item.Model #item.Badge #item.BodyStyle
#item.DriveType --&& Other stuff--
}
#*SortBy (in the same view)*#
<script>
$(document).ready(function () {
var SortDD = $('#SortDD');
var searchDiv = $('.searchDiv');
var carsList = '#Html.Raw(Json.Encode(Model.CarsList))';
//var carsList1 = JSON.stringify(carsList);
console.log("List: " + carsList);
SortDD.change(function () {
$.ajax({
//processData: false,
traditional: true,
dataType: 'html',
contentType: 'application/json; charset=utf-8',
data: { list: carsList,searchValue: SortDD.val() },
url: '#Url.Action("SortSearch", "DisplayAds")',
type: 'post',
success: function (response) {
searchDiv.empty();
if (response !== null) {
searchDiv.append(response);
} else {
searchDiv.append("Search returns null from sort DD");
}
},
error: function (ex) {
alert("Error from sort DD: ", ex.statusText);
}
});
});
});
</script>
And this is the controller which will receive the ajax
[HttpPost]
public PartialViewResult SortSearch(string searchValue, IEnumerable<UserCar> list)
{
ViewBag.SortDD = new SelectList(Utilties.GetSortDD(), "Value", "Text", searchValue);
switch (searchValue)
{
case "1":
list = list.OrderByDescending(x => x.AdCreationDate).ToList();
break;
case "2":
list = list.OrderByDescending(x => x.Odometer).ToList();
break;
case "3":
list = list.OrderBy(x => x.Make).ToList();
break;
--& other 10 cases--
var vmUserCar = new VMUserCar() { CarsList = list};
return PartialView("~/Views/Partial_Views/_DisplayAds/_SearchResultDisplay.cshtml", vmUserCar );
} --this is the same partial view which displays all the userCars --
When i run and ajax contains :
contentType: 'application/json; charset=utf-8',
It gives me "Invalid JSON primitive: list1." and doesn't continue to action...
& when i run without it, it goes to action but The list value on the controller is always null..
I tried '#Html.Raw(Json.Encode(Model.CarsList))' alone and value is null always but when i console.log it.... i get json values..
and JSON.stringify(carsList) also null but no values at all when i console log it...
When i changed the list value of controller to IEnumerable list
It retrieves the values as one long string line but i don't know how to convert it to UserCar class
Thanks again for taking the time to read all of that... any help will be much appreciated....
$(document).ready(function () {
function PassThings()
{
var things = [
{ id: 1, color: 'yellow' },
{ id: 2, color: 'blue' },
{ id: 3, color: 'red' }
];
things = JSON.stringify({ 'things': things });
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: $("body").attr("data-project-root") + "Administration/Actions/PassThings",
data: things,
success: function () {
$('#result').html('"PassThings()" successfully called.');
},
failure: function (response) {
$('#result').html(response);
}
});
}
PassThings();
});
For this Controller ::
public void PassThings(List<Thing> things)
{
var t = things;
}
For this ViewModel ::
public class Thing
{
public int Id { get; set; }
public string Color { get; set; }
}
Its must be work, and I recheck this.Would you please recheck this.

Json Data Not mapped in the backend service

I have a Spring MVC web application and I have the following web service.
#RequestMapping(value = "/newBill", method = RequestMethod.POST)
public #ResponseBody ModelMap acceptNewBill(#ModelAttribute ("Bill") Bill newBill ){
Bill bill = new Bill();
bill.setTableName(newBill.getTableName());
bill.setRoom(newBill.getRoom());
bill.setCovers(newBill.getCovers());
ModelMap model = new ModelMap();
model.put("status", true);
return model;
}
The following Script performs the front end functions.
$('.done').click(function(){
var jsonObject = createJSON(".newBill");
jQuery.ajax({
url: "/newBill",
type: "POST",
data: {bill: JSON.stringify(jsonObject) },
dataType: "json",
beforeSend: function(x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("application/j-son;charset=UTF-8");
}
},
success: function(result) {
alert('sadgsd');
}
});
});
function createJSON(elementToConvert) {
jsonObj = [];
$( elementToConvert + " input").each(function() {
var id = $(this).attr("class");
var email = $(this).val();
item = {}
item [id] = email;
jsonObj.push(item);
});
return jsonObj;
}
The above createJSON function go through a provided html element and puts the values into an object! The click function performs the POST and the Post contains the following data.
bill [{"tableName":"326432"},{"room":"3462346"},{"covers":"3426234"}]
Now when I debug and check the service, the data which goes from the front end doesn't get mapped in the parameter. I checked whether the variable names are the same as the POST. They are the same! but the values doesn't get mapped! Can any one please help me with this issue.
Update :
I changed the service method to GET and passed a value as a URL variable. Then it got mapped in the service param. The problem is in the POST.
Instead of using #ModelAttribute in your controller use #RequestBody:
public #ResponseBody ModelMap acceptNewBill(#RequestBody Bill newBill) {
On the ajax call, set the content type to application/json and stringify the whole object instead of just the array:
jQuery.ajax({
url: "/newBill",
type: "POST",
data: JSON.stringify({bill: jsonObject}),
dataType: "application/json",
beforeSend: function(x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("application/j-son;charset=UTF-8");
}
},
success: function(result) {
alert('sadgsd');
}
});

converted date time in json

i have a model,with jason send and fill this model but
when return a filled model by data and get it in view date time converted to :"/Date(1241465400000)/"
[Serializable]
public class MyModel
{
public int Id {get;set;}
public DateTime date {get;set;}
}
[HttpPost]
public ActionResult SchedulesDropdownIndexChanged(MyModel schedule)
{
objScheduleModel = new ScheduleModel();
objScheduleModel = schedule;
......fill model here date time is ok-----------
objScheduleModel.date=Datetime.Now;
return Json(objScheduleModel);
}
here is a dropdownlist when selected index chaned fired this function
$(function () {
$("select#SchedulesDropdown").change(function (evt) {
var ScheduleModel = getScheduleDateTime();
var json = $.toJSON(ScheduleModel);
var abc;
$.ajax({
url: "/Members/DropdownIndexChanged",
type: 'POST',
dataType: 'json',
data: json,
contentType: 'application/json; charset=utf-8',
success: function (msg) {
var o = msg.date;---------------unformated date time--------------->>> "/Date(1241465400000)/"
}
});
});
});
function getScheduleDateTime() {
var Id = $("select#SchedulesDropdown").val();
var to = $("#dateTo").val();
return (Id == "") ? null : { Id: Id, date: to };
}
jQuery extension to auto convert dates
This blog post might help. It's an extension that auto converts ISO as well as Asp.net dates.
I also suggest if you use this code to make the optional parameter to disable auto conversion so by default it simply converts dates. In your case (because you're not explicitly calling parseJSON) this will just convert it. And 99.9% of the time you do want auto conversion all the time.