AJAX call: Invalid web service call, missing value for parameter - javascript

My ajax call fails with the message in question.
[WebMethod(EnableSession = true)]
public static string UpdateTotalPrice(List<TicketPriceAjax> jsonTickets)
{
// some server-side processing
return "a string value";
}
The object Iʻm trying to pass
public class TicketPriceAjax
{
public string Fullname { get; set; }
public string Price { get; set; }
public string TicketDescription { get; set; }
}
My javascript which gets invoked on a change event
$("select.combobox").change(function(e) {
var ticketsArray = GetTicketsArray();
postTotalPrice(ticketsArray);
});
function GetTicketsArray() {
var tickets = {};
var prices = [];
tickets.prices = prices;
$("#divFullNames div.row").each(function () {
var price = {
"Fullname": $(this).find("input").val(),
"Price": $(this).find("select").val(),
"TicketDescription": $(this).find(":selected").text()
};
tickets.prices.push(price);
});
return tickets;
};
function postTotalPrice(prices) {
$.ajax({
type: "POST",
url: "Details.aspx/UpdateTotalPrice",
data: JSON.stringify(prices),
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
success: function (data) {
UpdateTotalPrice(data);
},
error: function(data, textStatus, jqXHR) {
console.log('error!', data, textStatus, jqXHR);
}
});
};
What am I doing wrong?

Change data part to this
data: JSON.stringify({jsonTickets:prices})
Your webmethod expects a parameter with name jsonTickets so you need to specify parameter name in data part.
Also you do not need to assign tickets.prices simply create an array and push objects in it and pass it to webmethod.This way you are creating a list and than assigning list to its property prices and in webmethod you are expecting a list.
var tickets = [];
$("#divFullNames div.row").each(function () {
var price = {
"Fullname": $(this).find("input").val(),
"Price": $(this).find("select").val(),
"TicketDescription": $(this).find(":selected").text()
};
tickets.push(price);
This will pass list to webmethods.

Related

Ajax POST an object with javascript, but the value in backend is null, why?

So on button click there is a function sendEmail(). Alert is working fine, I can see my datas there. But on backend I can't see anything, just everything is null.
function sendEmail() {
var datas = new Object();
datas.mail = $('#contactDropdownList').val();
datas.mailobject = $('#emailObject').val();
datas.text = $('#emailText').val();enter code here
alert(datas.mail + datas.mailobject + datas.text);
$.ajax({
type: "POST",
dataType: "json",
url: "/Email/sendEmail",
contentType: 'application/json; charset=UTF-8',
data: JSON.stringify({ items: datas }),
success: function (data) {
console.log(data);
//do something with data
},
error: function (jqXHR, textStatus, error) {
//log or alert the error
console.log(error);
}
});
}
C# code:
public class MyClass
{
public string Email { get; set; }
public string Object { get; set; }
public string Text { get; set; }
}
[HttpPost]
public IActionResult sendEmail(MyClass items)
{
return Json(new { data="Ok" });
}
items.Email, items.Object and items.Text are null.
And the return valu is null as well, because in javascript success: function (data) { console.log(data);
is empty string.
What can be the problem? Thank you!
Model binder expects json content to match C# class. Your datas object should look like that
var datas = {
email: $('#contactDropdownList').val(),
object: $('#emailObject').val(),
text: $('#emailText').val()
}
Since you wrapped your object ({ items: datas }), you may think it will be mapped to sendEmail(MyClass items), but in reality items name does not matter, you can change variable name to any other name you like
Make sure you apply [FromBody] attribute to your parameter like that
[HttpPost]
public IActionResult sendEmail([FromBody]MyClass items)
Complete demo:
<script>
function sendSmth() {
var data = {
Email: 'email',
Object: 'object',
Text: 'text'
};
$.ajax({
type: "POST",
dataType: "json",
url: "/home/index",
contentType: "application/json",
data: JSON.stringify(data),
success: function (datas) {
console.log(datas)
}
})
}
</script>
And controller
[HttpPost]
public IActionResult Index([FromBody]MyClass obj)
{
return View();
}
As someone has noted, you have a mismatch between what you're sending to the controller and what the model the modelbinder is expecting. You can also vastly simply your AJAX code:
function sendEmail() {
var data = {
Email: $('#contactDropdownList').val(),
Object: $('#emailObject').val(),
Text: $('#emailText').val()
};
$.post("/Email/sendEmail", data)
.done(function (response) {
console.log(response);
//do something with response
})
.fail(function (jqXHR, textStatus, error) {
//log or alert the error
console.log(error);
});
}
You don't really need to specify the content type or data type - the $.post helper's defaults work just fine for what you've shown.

Passing an object with values from View to ActionResult using ajax

I want to send an object from view to controller, ajax hits the action result but data is not being delivered to action result
View:
function submit()
{
var obj = {};
obj.PD = getResult('pd');
obj.MD = getResult('md');
obj.C = getResult('c');
obj.ME = getResult('me');
obj.EE = getResult('ee');
obj.SED = getResult('sed');
obj.RT = getResult('rt');
obj.SEA = getResult('sea');
$.ajax({
url: '/Assessment/AssessNow',
type: 'POST',
async: false,
data: '{obj' + JSON.stringify(obj) + '}',
dataType: 'json',
success: function (res) {
},
error: function (msg) {
}
});
//alert(getResult('pd'));
}
Model:
public class QAViewModel
{
public string C { get; set; }
public string EE { get; set; }
public string MD { get; set; }
public string ME { get; set; }
public string PD { get; set; }
public string RT { get; set; }
public string SEA { get; set; }
public string SED { get; set; }
}
Controller:
Editing as a good point was raised:
In the post you can just pass the full object like so:
function submit()
{
var obj = {};
obj.PD = getResult('pd');
obj.MD = getResult('md');
obj.C = getResult('c');
obj.ME = getResult('me');
obj.EE = getResult('ee');
obj.SED = getResult('sed');
obj.RT = getResult('rt');
obj.SEA = getResult('sea');
$.ajax({
url: '/Assessment/AssessNow',
type: 'POST',
async: false,
data: obj,
success: function (res) {
},
error: function (msg) {
}
});
//alert(getResult('pd'));
}
If you want to stick with json then modify your ajax call accordingly (you error was in the way you were building the data property:
$.ajax({
url: '/Assessment/AssessNow',
type: 'POST',
async: false,
data: JSON.stringify({obj: obj}),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (res) {
},
error: function (msg) {
}
});
Also, depending on what you are doing with the result you may need to flip your controller actions to return JsonResult (Ignore if you are doing something such as returning a partial view to load):
[HttpPost]
public JsonResult Whatever(QAViewModel obj)
{
return Json(whatever, JsonRequestBehavior.AllowGet);
}

Ajax call hits with null values

I have a array and I get data from the array and going to pass it to the controller through ajax call.
But the problem is it hits the controller side with all the null values.(Data not passes,null passes )
Client Side Code
for (var j = 0; j < NewsGlobalArray.length; j++) {
var NewsRequestModel = {
DESCRIPTION: NewsGlobalArray[j]['DESCRIPTION'] // news description comes here.i checked it with console.log
}}
$.ajax({
url: $('#addNewsRequest').val(),
type: "POST",
data: { newsRequest: NewsRequestModel },
dataType: "json",
success: function (referenceNo) {
//success
}
});
}
My Controller
[HttpPost]
public JsonResult AddNewsRequest(NewsRequestModel newsRequest) // hits here with null values
{
//Some coding goes here.
}
My Model
public class NewsRequestModel
{
public int NEWSREQUESTID { get; set; }
public string DESCRIPTION { get; set; }
}
Try this: just add traditional:true in ajax call
$.ajax({
type: "POST",
url: $('#addNewsRequest').val(),
data: JSON.Stringify({ newsRequest: NewsRequestModel }),
dataType: "json",
traditional:true,
success: function (res) {
//do something
}
});
I think you need to this:
var myObject = new Object();
myObject.name = "John";
myObject.age = 12;
then pass myObject to ajax call and get on controller by name.

Json array as json object is not passed properly to controller in ajax call

I have following javascript method to pass json object with some object and an arry to my controller. Json objects are assigned properly but array is empty what am I doing worn.
function setData() {
var quotation = {
ID : 0,
Number : "",
AccountName : getAccount(),
CurrencyID : getCurrencyID(),
Date: getQuoteDate(),
ExchangeRate :getExchangeRate(),
Percentage : getPercentage(),
PriceListId: getPriceListId(),
}
quotation.Items = [];
$.each(this.selectedItem.items, function (index, qitem) {
var Item = {
ID: 1,
ItemNumber:"lcfe"
};
quotation.Items.push(Item);
});
$.ajax({
url: '#Url.Action("CreateQuotation", "Main")',
data: quotation,
contentType: "application/json; charset=utf-8",
type: 'GET',
success: function (dat1a) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.responseText);
alert("Status: " + XMLHttpRequest); alert("Error: " + errorThrown);
}
});
}
My Model classes.
public class Quotation
{
public long ID { get; set; }
public string Number { get; set; }
public List<QuotationItem> Items { get; set; }
//....
}
public class QuotationItem
{
public long Id { get; set; }
public string ItemNumber { get; set; }
}
Here is result I seen in debug.
I can see 2 objects are added in List but their vlaues ID, ItemNumber are not assigned?
Any idea?

Post files and object in the same AJAX request

I have some data and files that should be posted in one same AJAX request. Tried some solutions but I always get null in the controller (files are sent fine and when I change Tester class to simple string it also works).
My JS:
function sendAjaxWithFile (formData, successCallback, errorCallback) {
successCallback = successCallback || function () { };
errorCallback = errorCallback || function () { };
$.ajax({
url: "/Test/Save",
type: "POST",
data: formData,
cache: false,
processData: false,
contentType: false,
success: successCallback,
error: errorCallback
});
}
var data = new FormData();
data.append("tester", { Name: "QWERTY" });
data.append("someFile", file);
$scope.sendAjaxWithFile(data, function (response, textStatus, jqXHR) {
}, function (jqXHR, textStatus, errorThrown) {
});
And the server side code:
[AjaxOnly]
[HttpPost]
[Route("Save")]
public async Task<JsonResult> Save(Tester tester, HttpPostedFileBase someFile)
{
return await Task.FromResult(Json(0));
}
Tester class:
public class Tester
{
public string Name { get; set; }
public DateTime Date { get; set; }
}
I did a workaround, because I don't think it can be resolved in a normal way...
My solution is to send string data which is serialized from my JS object.
data.append("serializedJsonString", JSON.stringify({ Name: "QWERTY" })); // I can serialize what I want to
I needed to change the parameter of my Save method to get JSON string data and convert it into Tester class manually:
[AjaxOnly]
[HttpPost]
[Route("Save")]
public async Task<JsonResult> Save(string serializedJsonString, HttpPostedFileBase someFile)
{
var decodedJson = HttpUtility.UrlDecode(serializedJsonString);
var jTester = JObject.Parse(decodedJson);
var tester = new Tester { Name = jTester["Name"].ToString() };
return await Task.FromResult(Json(0));
}

Categories

Resources