I´m having difficulties matching Javascript Ajax to ASP.NET Controller type. All parameters comes fine, except for the MsgData that comes null when received by the Controller.
My Controller classes and code:
public class AjaxMessage
{
public enum MsgStatusType : int { OK, NOK }
public string MsgType { get; set; }
public List<AjaxMessageItem> MsgData { get; set; }
public MsgStatusType MsgStatus { get; set; }
public string MsgStatusMsg { get; set; }
}
And
public class AjaxMessageItem
{
public string Name { get; set; }
public string Value { get; set; }
public AjaxMessageItem()
{
Name = String.Empty;
Value = String.Empty;
}
}
Finally:
public ActionResult Get(AjaxMessage ajaxMessage)
{
... do some stuff...
}
My Javascript call:
var url = '#Url.Action("Get", "AjaxServer")';
$.ajax({
url: url,
cache: false,
type: "POST",
data: {
'MsgType': 'MsgType1',
'MsgData': { 'Name': 'customerId', 'Value': 'current' },
'MsgStatus': 'OK',
'MsgStatusMessage' : ''
},
success: function (data) {
if (data.msgStatus != 'OK') {
var errorMsg = 'Error reading data.' + data.msgStatusMessage;
alert(errorMsg);
return;
}
... do some stuff...
}
},
error: function (data) {
alert('Error retrieving Ajax data.');
}
});
At controller, I´m getting MsgType, MsgStatus and MsgStatusMsg fine whan looking for ajaxMessage variable, but MsgData is always null and shall be receiving the customerId data.
I need some help to solve that. Please help me to find out what´s missing... Thanks.
Because you're sending an array, you will have to convert the object to JSON explicitly using JSON.stringify, wrap the MsgData in [] and set contentType: 'application/json, charset=utf-8'
$.ajax({
url: url,
cache: false,
type: "POST",
contentType: 'application/json, charset=utf-8',
data: JSON.stringify({
'MsgType': 'MsgType1',
'MsgData': [{ 'Name': 'customerId', 'Value': 'current' }],
'MsgStatus': 'OK',
'MsgStatusMessage' : ''
}),
success: function (data) {
if (data.msgStatus != 'OK') {
var errorMsg = 'Error reading data.' + data.msgStatusMessage;
alert(errorMsg);
return;
}
... do some stuff...
}
},
error: function (data) {
alert('Error retrieving Ajax data.');
}
});
your data is sent to server, but you cant get that correctly, you can check the network tab of your browser, or check data has been sent to server by something like this:
HttpUtility.UrlDecode(Request.Form.ToString())
i think the easiest way is always stringify your data, and deserializing that to your poco object on server
Related
The javascript side of things looks like this:
var self = this;
self.services = ko.observableArray([]);
self.saveServices = function () {
if (self.services().length > 0) {
var obj = JSON.stringify({ services: self.services() });
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: "POST",
url: '/Business/SaveServices',
data: obj,
success: function (data) {
$("#saveModal").modal('show');
if (!data) {
$("#saveDetails").text('Processing error, please try again or email us.');
return;
} else if (data === "saved") {
$("#saveDetails").text('Saved changes.');
setTimeout(function () {
$('#saveModal').modal('hide');
}, 2500);
} else {
$("#saveDetails").text(data);
}
},
error: function (error) {
$("#saveModal").modal('show');
$("#saveDetails").text('Processing error, please try again or email us.');
}
});
}
}
Then my controller looks like this:
[HttpPost]
public async Task<JsonResult> SaveServices([FromBody]SaveServicesRequest saveServicesRequest)
{
try
{
if (User.Identity.IsAuthenticated)
{
return Json("saved");
}
return Json("User is not authenticated.");
}
catch (Exception ex)
{
logger.Error(ex + ". Users Email address: " + User.Identity.Name);
return Json("Processing error, please try again or email us.");
}
}
public class SaveServicesRequest
{
public List<services> services { get; } = new List<services>();
}
public class services
{
public string service { get; set; }
}
Am hitting the controller but the array of items I'm expecting is not returned (saveServicesRequest is empty), I cannot seem to pass an array in any form. Anyone see what am doing wrong? The data/json is being sent client side, think the problem might lie in how am building the json and receiving it.
The problem is that you're initializing services to a new list in SaveServicesRequest. The properties should also have public getters and setters for model binding.
Try updating your class to:
public class SaveServicesRequest
{
public List<services> services { get; set; }
}
I'm trying to post a list of objects to a MVC controller via AJAX, but when it gets to the controller the editedPrices parameter is 0.
What am I doing wrong? Currently I'm not sure if the issue is with the data I'm sending or the controller.
Java Script:
$(document).ready(function () {
var newPrices = [
{ "id": "1", "wePrice" : "99", "wdPrice":"79" },
{ "id": "2", "wePrice" :"89", "wdPrice":"59" }
];
editedPrices = JSON.stringify(newPrices);
$.ajax({
contentType: 'application/json; charset=utf-8',
type: "POST",
url: "#Url.Action("EditRates")",
data: {editedPrices : newPrices},
dataType: "json",
success: function (msg) {
alert(msg);
},
error: function (req, status, error) {
alert(error);
}
});
});
c# object
public class EditPrices
{
public string id { get; set; }
public string wePrice { get; set; }
public string wdPrice { get; set; }
}
controller
[HttpPost]
public int EditRates(List<EditPrices> editedPrices )
{
return editedPrices.Count();
}
I've tried using the [FromBody] attribute, but then the editedPrices parameter is null (as opposed to showing a count of 0).
Edit
Just to clarify, I can see that some data is being sent in the AJAX request. And I can see that the controller is being called. So the AJAX request it self is working. But I'm either sending the data in the 'wrong' format, or there's something wrong with how I'm trying to receive it.
You should just change this line:
...
data: JSON.stringify(newPrices),
...
You are making another object with {editedPrices : newPrices}. Your API accepting array.
I have data like this
[{"billno":"111","amount":"2233.00"},{"billno":"222","amount":"2500.00"},{"billno":"333","amount":"3000.00"}]
I want to store this record in my database, So before that I am trying to send this records to server
Here is my AJAX code:
$('#btnAddVendor').click(function () {
var values = [];
$('table#ContentPlaceHolder1_GridView1 input.checkBoxClass:checked').each(function () {
var $row = $(this).closest('tr').children('td');
values.push({ 'billno': $row.eq(1).text(), 'amount': $row.eq(5).text() });
});
//html_data = JSON.stringify(values);
alert(JSON.stringify(values)); // this alert will display above values
$.ajax({
type: 'POST',
url: 'GPCreateCheque.aspx/setCheqVendorSearchEntry',
data: JSON.stringify(values),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
alert(result.d);
},
error: function (result) {
alert("Not save");
}
});
})
WebMethod code
public partial class WebForm5 : System.Web.UI.Page
{
[WebMethod]
public static string setCheqVendorSearchEntry(vendorEntry[] values)
{
//here I will write the code to store the records in database
return "Success"; //for testing I return this string
}
}
public class vendorEntry{
public string billno { get; set; }
public string amount { get; set; }
}
I don't know how to receive from ajax. Thanks
Update Error msg
http://localhost:55047/GPCreateCheque.aspx/setCheqVendorSearchEntry 500 (Internal Server Error)
I finally make it run by following:
You need to make it allowed for POST method
[System.Web.Services.WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false)]
public static string setCheqVendorSearchEntry(vendorEntry[] values)
{
return "Success"; //for testing I return this string
}
and Default.aspx, your Json Array was not proper. You need to take parameter name (here it is 'values' in setCheqVendorSearchEntry method) in json element and pass it as string or serialize.
var values = '{ "values": [{ "billno": "111", "amount": "2233.00" }, { "billno": "222", "amount": "2500.00" }, { "billno": "333", "amount": "3000.00" }] }';
$.ajax({
type: 'POST',
url: 'Default.aspx/setCheqVendorSearchEntry',
data: values,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
alert(result.d);
},
error: function (result) {
console.log(result);
}
});
For your learning purpose:
When you console your error in ajax error section, you can find exact error in browser console like this:
Image : https://prnt.sc/gw06sr
======================
Part 2
MVC controler's field1 always has null (Post([FromBody] TestModel field1) ) null values if I use JSON.stringify(MyDdata). Even on the simplest JSON strings.
I used an XML to JSON convert to make sure my JSON data was correct. (I still need to get to know JSON.) I would think the following would be easily consume by the MVC controller but the input parameter field1 is null. At the least, TestStrng & TestStrng2 should have values.
The controller isn't crashing but it isn't understanding the JSON either.
Why doesn't the MVC Controler know the JSON class?
//JavaScript
var MyDdata =
{
"TestModel": {
"TestStrng": "Scott",
"TestStrng2": "SomethingElse",
"Usr": { "UsrToken": "aaaa" },
"LstSubClass": {
"SubClass": [
{ "FirstName": "Beth" },
{ "FirstName": "Julie" },
{ "FirstName": "John" }
]
}
}
}
sdata = JSON.stringify(MyDdata);
$.ajax({
type: 'post',
url: serviceUrl,
cache: false,
data: sdata,
dataType: "json",
}).done(function (data) {
//C# Class
public class Usr
{
public string UsrToken { get; set; }
}
public class SubClass
{
public string FirstName { get; set; }
}
public class TestModel // Main\Master Class
{
public string TestStrng { get; set; }
public string TestStrng2 { get; set; }
public List<SubClass> LstSubClass = new List<SubClass>();
private Usr _Usr = new Usr();
public Usr oUsr
{
get { return _Usr; }
set { _Usr = value; }
}
}
//MVC Controller
[System.Web.Http.Description.ResponseType(typeof(TestModel))]
public HttpResponseMessage Post([FromBody] TestModel field1)
{
// ...
}
//XML Data
<TestModel>
<TestStrng>Scott</TestStrng>
<TestStrng2>SomethingElse</TestStrng2>
<Usr>
<UsrToken>aaaa</UsrToken>
</Usr>
<LstSubClass>
<SubClass><FirstName>Beth</FirstName></SubClass>
<SubClass><FirstName>Julie</FirstName></SubClass>
<SubClass><FirstName>John</FirstName></SubClass>
</LstSubClass>
</TestModel>
JSON Data
{
"TestModel": {
"TestStrng": "Scott",
"TestStrng2": "SomethingElse",
"Usr": { "UsrToken": "aaaa" },
"LstSubClass": {
"SubClass": [
{ "FirstName": "Beth" },
{ "FirstName": "Julie" },
{ "FirstName": "John" }
]
}
}
}
======================
Part 1
I am trying to learn Web API in C# and have spent a day on this one problem. The problem is in JavaScript with "data: ...".
hardcoded this works
Ajax data: {'TestStrng': 'one', 'TestStrng2': 'two' }
Below in the controller, as expected, the p_TestModel contains the values 'one' & 'two'.
public HttpResponseMessage Post(TestModel p_TestModel)
BUT
the data is NOT passed from JS to Controller if I use a variable like data: sdata.
I have tried tens of ways and many I am too embarrassed to write:
var sdata = "'TestStrng': 'one', 'TestStrng2': 'two'";
sdata = "'TestStrng': 'one'";
var jsonString = JSON.stringify(sdata);
JSON.stringify(sdata); {
'TestStrng': 'one',
'TestStrng2': 'two'
}, {
'TestStrng': 'one',
'TestStrng2': 'two'
}, {
field1: "hello"
},
data: {
sdata
},
'TestStrng': 'onetwo'
},
"{ 'TestModel': { 'TestStrng': 'one', 'TestStrng2': 'two' } }",
JSON.stringify(sdata),
sdata,
sdata = "'TestStrng': 'one', 'TestStrng2': 'two'";
data: {
TestModel,
sdata
},
Question
What am I doing wrong?
Why won't a JS variable send the data so the controller can see it as if it is hardcoded?
C# class
public class TestModel {
public string TestStrng { get; set; }
public string TestStrng2 { get; set; }
}
MVC Controller
[System.Web.Http.Description.ResponseType(typeof(TestModel))]
public HttpResponseMessage Post(TestModel p_TestModel)
{
// p_TestModel has correct values if hardcoded in JS.
// It is ALWAYS null if JS uses a variable (sData) to send it.
...
}
JavaScript
$.ajax({
type: 'post',
url: serviceUrl,
cache: false,
dataType: "json",
data: sdata, <<<<<<<<<<????
}).done(function (data) {
Create a javascript object and use that. This should work.
var sdata= { TestStrng :"Scott",TestStrng2:"SomethingElse" };
$.ajax({
type: 'post',
url: serviceUrl,
data: sdata
}).done(function (data) { console.log(data) });
If your view model is a flat view model without any complex navigational properties, the above code will work fine. But if you have complex properties on your view model, You need to convert the js object to a JSON String and set the contentType property
var model= { Name:"S",Address: { City:"Detroit"} };
$.ajax({
type: 'post',
url: serviceUrl,
data: JSON.stringify(model),
contentType: "application/json"
}).done(function (data) { console.log(data) });
Take a look at this answer explaining different approaches for sending data from your client js code to your web api endpoint.
I have a test js function that should post data to webapi by Post method
function test() {
var puffs = [];
var puffObject = {
id: "2735943",
priority: "1"
};
puffs.push(puffObject);
puffs.push(puffObject);
var dto =
{
po: puffs
};
$.ajax({
type: "POST",
url: "../api/PuffPriority/",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(dto),
dataType: "json",
success: function (data, status) {
if (data) {
console.log("Welcome");
} else {
console.log("No data");
}
},
error: function (error) {
console.log("Error");
}
});
}
In the controller class i have
public void Post(PuffPriority[] po){
//Do something here with po, but po is always empty
}
where PuffPriority Model is
public class PuffPriority
{
public string id { get; set; }
public string priority { get; set; }
}
I dont know whats wrong , the values are sent by JS but api Controller don't fetch it :( Please help, i have already wasted a lot of time.
You have a bug in your code.
Simply change
url: "../api/PuffPriority/"
to
url: "../api/Post/"
or change your method name from Post to PuffPriority
Changed
public void Post(PuffPriority[] po){
//Do something here with po, but po is always empty
}
To
[FromBody]List<PuffPriority> po{
//Do something here with po, but po is always empty
}