JsonConvert.SerializeObject in Asp.Net MVC - asp.net

Im retrieving data in database using ajax but when I'm calling the method in controller I getting an error in JsonConvert.SerializeObject(model, Formatting.Indented, new JsonSerializerSettings and I don't know why. Here's my code:
Views
function EditRecord(Id) {
var url = "/Admin/GetCategoryGroupById?Id=" + Id;
$("#ModalTitle").html("Update Category Group");
$("#MyModal").modal();
$.ajax({
type: "GET",
url: url,
success: function (data) {
var obj = JSON.parse(data);
$("#Id").val(obj.Id);
$("#Name").val(obj.Name);
//$("#Status option:selected").text(obj.tblDepartment.DepartmentName);
$("#cbStatus").val(obj.Status);
}, error: function (xhr, status, error) {
alert(error);
}
})
}
Controllers
public JsonResult GetCategoryGroupById(int Id)
{
CategoryGroup model = db.CategoryGroups.Where(x => x.Id == Id).SingleOrDefault();
string value = string.Empty;
value = JsonConvert.SerializeObject(model, Formatting.Indented, new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
return Json(value, JsonRequestBehavior.AllowGet);
}
The error:
Please help me. Thank you.

i think that your db doesn't have any CategoryGroups with the specified id. this is why the singleOrDefault returns null. so you need to add an if statement to check weather model is null

Related

How to pass a two dimensional Javascript array from view to controller - Asp.net Core 6 MVC

I am totally new to Asp.Net Core and I am trying to implement an Inventory controlling system. Now I am facing a problem of saving sales data to database. The main problem is I have failed to bring data to controller. I have 'sales', 'SalesProducts' and 'products' tables in database. What I have tried so far,
Sales Create View has a dropdown to select products and it populates using SalesViewModel:
SalesViewModel
public class SalesViewModel
{
public Sale Sale { get; set; }
public List<SelectListItem> Products { get; set; }
}
To create sales items list, each time user select a product and it's quantity, 'subArray' will be created and that item array will be pushed to 'SalesItemArray',
$('.btn-sales-add').on('click', function () {
let subArray = [];
let productId = $('#product-id').val();
let productName = $('#product-id option:selected').text();
let price = $('#sales-price').val();
let quanity = $('#sales-quantity').val();
let subTotal = $('#sales-sub-total').val();
quanity = parseInt(quanity);
subTotal = parseFloat(subTotal);
total += subTotal;
$('#sales-total input').val(total);
subArray.push(productId);
subArray.push(productName);
subArray.push(price);
subArray.push(quanity);
subArray.push(subTotal);
salesItemsArray.push(subArray);
});
Array Format
[[pro_id, pro_name, quantity, subTotal],[pro_id, pro_name, quantity, subTotal]]
To bring the sales data and sales items to controller, I used FormData object and another FormDataViewModel as shown in this solution
SalesFormDataViewModel
public class SalesFormDataViewModel
{
public string StoreId { get; set; }
public string Total { get; set; }
public string[] SalesItemList { get; set; }
}
I am passing SalesViewModel to view and passing SalesFormDataViewModel to controller. I am posting the data using Ajax,
let storeId = $("#sales-store-id").val();
let total = $("#sales-total input").val();
let salesItemList = salesItemsArray;var
formData = new FormData();
formData.append("StoreId", storeId);
formData.append("Total", total);
formData.append("salesItemList", salesItemList);
$.ajax({
url: '/api/sales/createSales',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(formData),
success: function (response) {
alert('success');
},
error: function (response, error) {
alert('error');
}
});
The Controller
[HttpPost]
[Route("createSales")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> createSales(SalesFormDataViewModel
salesFormDataViewModel)
{
return Ok(new { success = "Stock updated successfully" });
}
Actually, I have tried almost every solutions searching the web but whatever tried, everytime I get same error response. I can not even reach to the breakpoint in controler because ajax throws an exception.
Ajax Response
Please, I am expecting all of your help. Thank you.
I am Editing this question to add more details. After trying Chens solution now getsthis error
I could not pass the array until I changed my viewModel. I had to remove the string array type to string type.
public class SalesFormDataViewModel
{
public string StoreId { get; set; }
public string Total { get; set; }
public string SalesItemList { get; set; }
}
Then, I appended the array to formData after converting the array to json string.
formData.append("SalesItemList", JSON.stringify(SalesItemList));
After searching through how to send formData to controller, before sending the formData object directly via ajax, I had to do following.
let dataObj = {};
formData.forEach((value, key) => {
dataObj[key] = value;
});
Then ajax call:
let jsonData = JSON.stringify(dataObj);
$.ajax({
url: '/api/Sales/createSales',
method: 'POST',
contentType: 'application/json',
data: jsonData,
processData: false,
cache: false,
success: function (response) {
alert("success");
},
error: function (response) {
alert("error");
}
});
This way I was able to paas two dimensional js array from view to controller. However with this I was unable to achieve save passed object to database since the SalesItemList array being received is a Json array, an exception Cannot deserialize the current JSON array, is thrown when trying to deserialze that array to object in sales controller. So, instead of passing an array of array, passing an array of object, same as above solved the issue.
let SalesItemList = [{},{}];
I am posting this answer thinking it would help those who face same problem and want to highlight that I am ended up with this solution thanks to those who reply to this question.
The 400 response is due to you not passing ValidateAntiForgeryToken.It is easy to forget about the anti-forgery token when crafting a POST request made with AJAX. If you omit the value from the request, the server will return a 400 Bad Request result. Please check if you are passing the correct Token.
Method one:
Add headers manually:
$.ajax({
//...
headers: { "RequestVerificationToken": yourtoken },
//...
});
For more detail, you can refer to this link.
Method two:
Comment out ValidateAntiForgeryToken:
//[ValidateAntiForgeryToken]
Edit:
Let's troubleshoot your mistakes step by step:
View:
Assuming the formData you got is correct, it should be something like this(Pay attention to several properties of ajax):
<script>
function Test()
{
let storeId = 1;
let total = "Total";
let salesItemList = [[1, "Name1", "quantity1", "subTotal1"], [2, "Name2", "quantity2", "subTotal2"]];
var formData = new FormData();
formData.append("StoreId", storeId);
formData.append("Total", total);
formData.append("salesItemList", salesItemList);
$.ajax({
url: '/createSales',
method: 'POST',
data: formData,
processData: false,
contentType: false,
cache: false,
async: false,
success: function (response) {
alert('success');
},
error: function (response, error) {
alert('error');
}
});
}
</script>
Controller:
[HttpPost]
[Route("createSales")]
public async Task<IActionResult> createSales(SalesFormDataViewModel
salesFormDataViewModel)
{
return Ok(new { success = "Stock updated successfully" });
}

Getting Method Not Allowed when using AngularJS Delete

I'll be glad to get your help. I'm using AngularJS version 1.6.5 and trying to use http delete method. On server side i'm using asp.net MVC5 Web API.
When i'm trying to delete a record i'm getting error 405 (Method Not Allowed).
This is my AngularJS code:
$scope.Delete = function (CustomerNumber) {
$http.defaults.headers["delete"] = {
'Content-Type': 'application/json,charset=utf-8'
};
$http({
method: "DELETE",
url: "/Api/Customer/" + CustomerNumber
}).then(function successCallback(response) {
$scope.Customers = response.data;
$scope.addCustomer.$setPristine();
$scope.addCustomer.$setUntouched();
$scope.Customer = {};
$scope.error = "";
}, function errorCallback(response) {
$scope.error = "Error on delete customer (" + response.status + ") - " + response.statusText;
});
};
and this is my asp.net code:
public List<Customer> Delete(string CustomerNumber)
{
DataLayer dal = new DataLayer();
CustomerViewModel cvm = new CustomerViewModel();
Customer cust = (from x in dal.Customers where x.CustomerNumber == CustomerNumber select x).ToList<Customer>()[1];
dal.Customers.Remove(cust);
dal.SaveChanges();
cvm.customers = dal.Customers.ToList<Customer>();
return cvm.customers;
}
I tried many ways and none of them worked. I would like to get your help.
Thank you.
Use JSON.stringify
$http({
method: "DELETE",
url: "/Api/Customer/" + JSON.stringify(CustomerNumber)
})

Can't send data with $http.post in Ionic Framework

I'm trying make an application with Ionic framework which can take and send data to MS SQL server. For this I am using web api. I have no problem with taking data but something wrong with send new datas. Here is my ionic code :
angular.module('starter.controllers',[])
.controller('CheckListCtrl', function($scope, ChecklistService, $ionicPopup) {
function addCheck(){
ChecklistService.addCheck()
}
.factory('ChecklistService', ['$http', function ($scope, $http) {
var urlBase = 'http://localhost:56401/api';
var CityService = {};
CityService.addCheck = function(){
var url = urlBase + "/TBLCHECKLISTs"
var checkdata = {
AKTIF : true,
SIL : false,
KAYITTARIHI : Date.now(),
KULLANICIID : 3,
BASLIK : "Onur",
TAMAMLANDI : false,
TAMAMLANMATARIHI : null,
GUN : 1
}
var request = $http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: checkdata
});
return request;
}
return CityService;
}]);
And here is my web api:
[HttpPost]
[ResponseType(typeof(TBLCHECKLIST))]
public IHttpActionResult PostTBLCHECKLIST(TBLCHECKLIST tBLCHECKLIST)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
tBLCHECKLIST.KAYITTARIHI = DateTime.Now;
db.TBLCHECKLISTs.Add(tBLCHECKLIST);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = tBLCHECKLIST.TABLEID }, tBLCHECKLIST);
}
When i try to send i get this exception:
After, I realize that I take that exception because my checkdata is never come to web api. I don't know why.
These are not the datas I send:
I have tried different versions of post request but nothing. When I try to send data with PostMan, it works and I can insert data to my database. But why I can't do it with my application? Can anybody help me?
I think this should be the problem:
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
Try this:
return $http.post(url, checkdata);
And in your API:
[HttpPost]
[ResponseType(typeof(TBLCHECKLIST))]
public IHttpActionResult PostTBLCHECKLIST([FromBody]TBLCHECKLIST tBLCHECKLIST)
{
//code here
}
Also, make sure your checkdata properties match the ones in your TBLCHECKLIST c# type.

AngularJS Get Method Not Work

I have an angular application, and I am trying to get a list of users from the server. I ran into an issue. I have page call CurrentUsers. If CurrentUsers method returns a Json Object, the entire object is display on the page regardless of what I do in the app controller and html page. If the method return a view, it does not display anything. However, I can hard code the json object in the cotroller, and it will work fine.
As a result, I created another method to return the json object. I made a call to that method, but it never reached the server. Your help will be very much appreciated.
The CurrentUsers Method returning a JSON Object, the entire json object display on the screen regardless
[HttpGet]
public JsonResult CurrentUsers()
{
List<Users> currentUser = new List<Users>()
{
new Users{ UserName = "JDoe", Professor="SSmith", Course = "English1"},
new Users{ UserName = "ADan", Professor="SDhor", Course = "Science"},
new Users{ UserName = "ADes", Professor="SCarry", Course = "Religion101"},
new Users{ UserName = "DJay", Professor="SCrowe", Course = "Teaching101"},
new Users{ UserName = "MAnne", Professor="TRow", Course = "PreCalc"},
};
return Json(new { Ok = true, data= currentUser });
// return View();
}
If the above method return a View, I can modify the controller as
shown below, and I will see the appropriate Information
Registration.controller('CurrentUsersController', function ($scope, $http) {
$scope.currentUsers = [{ "Professor": "SSmith", "UserName": "JDoe", "Course": "English1" }, { "Professor": "SDhor", "UserName": "ADan", "Course": "Science" }, { "Professor": "SCarry", "UserName": "ADes", "Course": "Religion101" }]
});
I modified the controller to use a service and created the method below to read the Current Users so that the view can simply return a View(). However, I have not been able to get the 'GET'to work.
[HttpGet]
public JsonResult GetUsers()
{
List<Users> currentUser = new List<Users>()
{
new Users{ UserName = "JDoe", Professor="SSmith", Course = "English1"},
new Users{ UserName = "ADan", Professor="SDhor", Course = "Science"},
new Users{ UserName = "ADes", Professor="SCarry", Course = "Religion101"},
new Users{ UserName = "DJay", Professor="SCrowe", Course = "Teaching101"},
new Users{ UserName = "MAnne", Professor="TRow", Course = "PreCalc"},
};
return Json(new { Ok = true, data = currentUser , message =
"Success"}, JsonRequestBehavior.AllowGet);
}
the modify CurrentUsers Method to return a view
public ActionResult CurrentUsers()
{
return View();
}
My modify controller
Registration.controller('CurrentUsersController', function ($scope, GetUSerService) {
$scope.message = 'this is the Current User controller';
$scope.currentUsers = [];
var result = GetUSerService.getData()
.then(function (result) {
console.log('the result');
console.log(result.data);
});
});
my service
Registration.service('GetUSerService', function ($http,$q) {
this.getData = function () {
var deferredObject = $q.defer();
$http.get('/Home/GetUsers').
success(function (data) {
console.log('service call data');
console.log(data);
deferredObject.resolve({ success: true, data : data.data });
}).
error(function () {
deferredObject.resolve({ success: false, data : '' });
});
return deferredObject.promise;
};
});
Updated 10/6 #5:50
#FernandoPinheiro answer works for me. The only thing is that the GetUsers action is being called twice.
Updated 10/7
I figured out why the post was being done twice. On my template, I had ng-app="Registration", and I had ng-controller= "CurrentUsersController". Because I specified the controller name in the route provider, I did not need it to add it to the partial view. As soon as I removed it from the view, it worked as expected.
Your GetUserService is calling $http.post('/Home/GetUsers') instead of $http.get('/Home/GetUsers').
Besides, shouldnt you set the Route attribute for the action ?

return json error on asp.net not working

I m trying to test an error in Json notation, via an ajax call. This is my server method
[System.Web.Services.WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string publicarError()
{
try
{
throw new Exception("error");
}
catch (Exception ex)
{
Dictionary<string, object> error = new Dictionary<string, object>();
error.Add("success", false);
error.Add("message", "Something really bad happened");
string output = JsonConvert.SerializeObject(error);
return output;
}
}
This is my ajax call
$.ajax({
type: "POST",
url: pageUrl + '/publicarError',
data: '{valor: ' + $('#<%=classroomDropDownList.ClientID%>').val() + '}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () { alert('ok'); },
error: function (xhr, textStatus, exceptionThrown) {
var json = xhr.responseText;
var result = [];
result = eval('(' + json + ')');
var errorMessages = [];
//this ugly loop is because List<> is serialized to an object instead of an array
for (var key in result) {
errorMessages.push(result[key]);
}
$('#result').html(errorMessages.join("<br />"));
},
But when I run the example , it always enter on succes function, and not on the error one.
I dont know why. Is there any mistake?
That's the normal behaviour. You are not returning an error, you are returning a valid JSON object, so it goes to the success function. To go to the error function, you need to throw an exception. Comment out the try ... catch and the throw new Exception("error"); will go to the error function.

Resources