Sending JSON object successfully to ASP.NET WebMethod, using jQuery - asp.net

I've been working on this for 3 hours and have given up.
I am simply trying to send data to an ASP.NET WebMethod, using jQuery.
The data is basically a bunch of key/value pairs. So I've tried to create an array and adding the pairs to that array.
My WebMethod (aspx.cs) looks like this (this may be wrong for what I'm building in JavaScript, I just don't know):
[WebMethod]
public static string SaveRecord(List<object> items)
{
...
}
Here is my sample JavaScript:
var items = new Array;
var data1 = { compId: "1", formId: "531" };
var data2 = { compId: "2", formId: "77" };
var data3 = { compId: "3", formId: "99" };
var data4 = { status: "2", statusId: "8" };
var data5 = { name: "Value", value: "myValue" };
items[0] = data1;
items[1] = data2;
items[2] = data3;
items[3] = data4;
items[4] = data5;
Here is my jQuery AJAX call:
var options = {
error: function(msg) {
alert(msg.d);
},
type: "POST",
url: "PackageList.aspx/SaveRecord",
data: { 'items': items },
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: function(response) {
var results = response.d;
}
};
jQuery.ajax(options);
I get the error:
Invalid JSON primitive: items.
So, if I do this:
var DTO = { 'items': items };
and set the data parameter like this:
data: JSON.stringify(DTO)
Then I get this error:
Cannot convert object of type \u0027System.String\u0027 to type \u0027System.Collections.Generic.List`1[System.Object]\u0027

In your example, it should work if your data parameter is:
data: "{'items':" + JSON.stringify(items) + "}"
Keep in mind that you need to send a JSON string to ASP.NET AJAX. If you specify an actual JSON object as jQuery's data parameter, it will serialize it as &k=v?k=v pairs instead.
It looks like you've read it already, but take another look at my example of using a JavaScript DTO with jQuery, JSON.stringify, and ASP.NET AJAX. It covers everything you need to make this work.
Note: You should never use JavaScriptSerializer to manually deserialize JSON in a "ScriptService" (as suggested by someone else). It automatically does this for you, based on the specified types of the parameters to your method. If you find yourself doing that, you are doing it wrong.

When using AJAX.NET I always make the input parameter just a plain old object and then use the javascript deserializer to covert it to whatever type I want. At least that way you can debug and see what type of object the web method in is recieving.
You need to convert your object to a string when using jQuery
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="sm" runat="server" EnablePageMethods="true">
<Scripts>
<asp:ScriptReference Path="~/js/jquery.js" />
</Scripts>
</asp:ScriptManager>
<div></div>
</form>
</body>
</html>
<script type="text/javascript" language="javascript">
var items = [{ compId: "1", formId: "531" },
{ compId: "2", formId: "77" },
{ compId: "3", formId: "99" },
{ status: "2", statusId: "8" },
{ name: "Value", value: "myValue"}];
//Using Ajax.Net Method
PageMethods.SubmitItems(items,
function(response) { var results = response.d; },
function(msg) { alert(msg.d) },
null);
//using jQuery ajax Method
var options = { error: function(msg) { alert(msg.d); },
type: "POST", url: "WebForm1.aspx/SubmitItems",
data: {"items":items.toString()}, // array to string fixes it *
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: function(response) { var results = response.d; } };
jQuery.ajax(options);
</script>
And the Code Behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Serialization;
using System.Web.Script.Services;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CustomEquip
{
[ScriptService]
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static void SubmitItems(object items)
{
//break point here
List<object> lstItems = new JavaScriptSerializer().ConvertToType<List<object>>(items);
}
}
}

The following is a code snippet from our project - I had trouble with not wrapping the object as a string and also with Date values - hopefully this helps someone:
// our JSON data has to be a STRING - need to send a JSON string to ASP.NET AJAX.
// if we specify an actual JSON object as jQuery's data parameter, it will serialize it as ?k=v&k=v pairs instead
// we must also wrap the object we are sending with the name of the parameter on the server side – in this case, "invoiceLine"
var jsonString = "{\"invoiceLine\":" + JSON.stringify(selectedInvoiceLine) + "}";
// reformat the Date values so they are deserialized properly by ASP.NET JSON Deserializer
jsonString = jsonString.replace(/\/Date\((-?[0-9]+)\)\//g, "\\/Date($1)\\/");
$.ajax({
type: "POST",
url: "InvoiceDetails.aspx/SaveInvoiceLineItem",
data: jsonString,
contentType: "application/json; charset=utf-8",
dataType: "json"
});
The server method signature looks like this:
[WebMethod]
public static void SaveInvoiceLineItem(InvoiceLineBO invoiceLine)
{

Decorate your [WebMethod] with another attribute:
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
I believe this is in System.Web.Services.Scripting...

see link http://www.andrewrowland.com/article/display/consume-dot-net-web-service-with-jquery

This is the way you define your data (JSON)
data: { 'items': items },
and the this the way it should be
data: '{ items: " '+items +' "}',
basically you are serializing the parameter.

Related

WebMethod access page control and set value

My page name
public partial class AtamaGorevDegistir : System.Web.UI.Page
{}
My webmethod ajax side
var path = getLocation(location.href);
$.ajax({
type: "POST",
url: path.pathname + "/KisiBilgiDoldur",
// data: "{" + str + "}",
contentType: "application/json; charset=utf-8",
// dataType: "json",
success: function (data) {
var dd = data.d;
$('.modal-dialog').css({ width: '85%' });
$('#AtamaModal').modal({ show: true });
}
});
My webmethod
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string KisiBilgiDoldur(string KayitID, string TeklifID)
{
AtamaGorevDegistir atama = new AtamaGorevDegistir();
atama.AtananSuren.Value = "123";
return null;
}
But my problem my Control is null . But i can access this method but didnt set value and give error message. Why this happened?
WebMethod and ScriptMethod can't access the controls collection of the calling page. Think of it as outside the normal Web Forms lifecycle. When you use AJAX, you need to pass all data to the server side method it needs, and your server side should return all data that the client side needs. Then the client side should take that returned data and manipulate the DOM as necessary to display the result.
In your WebMethod, return the data instead of trying to assign it to a control, remove the return null;.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string KisiBilgiDoldur(string KayitID, string TeklifID)
{
return "123";
}
In your client side success handler, get the returned data and set the value of the control using JavaScript.
var path = getLocation(location.href);
$.ajax({
type: "POST",
url: path.pathname + "/KisiBilgiDoldur",
// data: "{" + str + "}",
contentType: "application/json; charset=utf-8",
// dataType: "json",
success: function (data) {
var dd = data.d;
$('.modal-dialog').css({ width: '85%' });
$('#AtamaModal').modal({ show: true });
//set control value to data.d here
}
});
You don't set the control value with a webmethod. Your return a value and from the api and do something with it, in the browser. Working with webmethods are not like webforms. The value you return in your webmethod is null... you're setting that null value into 'dd' in js, but you don't do anything with it. When you get your value back from the webmethod you need to do something with it. try 'alert(data.d)' in your success callback to see what i mean. Then $('#elm').text(data.d) if you want it on the page.
You should add parameters to data.
$.ajax({
type: "POST",
url: path.pathname + "/KisiBilgiDoldur",
data:JSON.stringify({ KayitID: '1', TeklifID:'2' }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var dd = data.d;
$('.modal-dialog').css({ width: '85%' });
$('#AtamaModal').modal({ show: true });
}
});

Add ASP.NET Image from Page Method

I am making an Ajax request with data to a Page Method in my code behind in my ASP.NET Web Forms application. I have a Panel control in my aspx page but I cannot get the control from that Page Method with its ID. I can get it from the Page_Load event though. What can I do to get the Panel control from the page method or is it not possible or maybe an alternative?
<asp:Panel ID="pnlImages" runat="server"></asp:Panel>
<script type="text/javascript">
function GetProductId() {
$.ajax({
type: "POST",
url: "Default.aspx/GenerateQrCode",
data: "{'Products':" + JSON.stringify(data) + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(xhr.responseText);
alert(thrownError);
},
success: function (msg) {
alert('Success');
}
});
}
</script>
[WebMethod]
public static void GenerateQrCode(List<Product> Products)
{
foreach(var product in Products)
{
string qrCodeLocation = products.Where(pid=>pid.ProductId == product.ProductId).Select(s=>s.QrCode).FirstOrDefault().ToString();
Image image = new Image();
image.ID = product.ProductId.ToString();
image.ImageUrl = qrCodeLocation;
//Cannot get 'pnlImages' here
}
}
You won't be able to do that, WebMethod doesn't follow the same flow as normal page methods. It's not even a instance method but static.
You'll have to return the information on client and create the image there using javascript.

parsing json response to C# object using jquery

I have following JSON returned from my WCF service:
`{"DoWorkResult":[{"AAID":0,"AreaID":1,"AreaName":"Basement","AssemblyAssessmentID":1,"AssemblyID":493,"AssemblyName":"Handrail (Steel)","AssessmentID":1,"AssessmentName":"University Of WA","AttributesCount":1,"CapitalReplacementUnitCost":623,"CategoryID":7,"CategoryName":"Furniture and Fixtures","CountedUnits":7,"CreatedBy":"Admin","ElementID":37,"ElementName":"Handrails and Balustrades","FacilityID":1,"FacilityName":"Central Chilled Water Plant","FacilityPercentage":"0","IsCompleted":1,"IsHeritage":false,"IsSafetyRisk":false,"Level1Units":0,"Level2Units":0,"Level3Units":0,"Level4Units":0,"Level5Units":7,"MesurementUnit":"Items","PhotosCount":1,"RepairCost":0,"RepairNotes":"","RequiresSpecialist":false,"SiteName":"CRAWLEY","SpaceID":1,"SpaceName":"B01","TasksCount":0}]}
My service method is like this
[System.ServiceModel.OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
public List<BLL.BLL_AssemblyAssessment> DoWork(string id) {
return BLL.BLL_AssemblyAssessment.GetAssessemblyAssessmentByAssemblyAssessmentID(1, 1);
}
and I need data parsed in jquery ajax success. how can i parse it to object of my class:
$.ajax({
type: "POST",
url: "MyTestService.svc/DoWork",
data: '{"id":"3"}',
processData: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
alert(data);
},
error: function (msg) {
// $("#errorDiv").text(msg);
alert(msg);
}
});
}
Use
alert(JSON.parse(jsonString));
In your javascript code, calling the $.ajax function with the dataType: "json" option lets jQuery take care of the parsing.
The data variable in the success callback is already a javascript object.
You can access its properties :
success: function(data) {
var html = "",
rows = data.DoWorkResult,
lgth = rows.length,
i, row;
for ( i=0; i<lgth; i++ ){
row = rows[i];
html += "<tr><td>"+row.AAID+"</td><td>"+row.AreaName+"</td></tr>";
// or whatever
}
$("#myTable").html( html );
}
From what I understand, the class BLL.BLL_AssemblyAssessment is a C# class, to be used on the server side, not a javascript class on the client side. In javascript, objects don't need a class definition to hold data.
You can output an object to the console to check its structure :
success: function(data) {
console.log(data);
console.log(data.DoWorkResult);
console.log(data.DoWorkResult[0]);
}
I don't really see the problem.
Since you have specified JSON as the datatype, the JSON is parsed in to a javascript object in the success handler. Just iterate over it using $.each:
//data.DoWorkResult is an array with one element
$.each(data.DoWorkResult, function(k, v){
alert(v.AAID); //will alert 0 one time since there is only one object in the
//array and the value is 0 on the AAID property
});
Fiddle
Note that I need to parse the JSON in my example, since it isnt automatically done by any ajax method there.

how to get the posted data in c#

I use ajax in my applicataion, and I have to use the $.post method.
Normally, the data sent to server are key-value paires. I can get them through:
HttpContext.Current.Request.QueryPara['name'];
....
But in some cases, the data to be sent to the server does not contain the name.
It is just a xml segments.
Like this:
var data='<data>xxxxx<data>';
$.post('http://server/service.asmx/test',data,function(){
//callback
},'xml');
Then How can I get the data in my webmethod?
You should have to use 'json' dataType to pass data to the web-method.
Have a look at sample:
Service.asmx
[ScriptService]
[WebService(Namespace = "http://localhost/testapp/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService{
[WebMethod]
public int Square(int no){ return no * no;}
}
and JavaScript code to request this webmethod
<script type="text/javascript">
$(function () {
$("#button1").click(function () {
$.ajax({
type: "post",
url: "service.asmx/Square",
data: "{no: 10}",
dataType: "json",
contentType: "application/json",
success: function (data) {
alert("Result :" + data.d);
},
error: function (src,type,msg) {
alert(msg); //open JavaScript console for detailed exception cause
}
});
});
});
</script>
<body>
<input type="button" id="button1" value="Square" />
</body>
I am not sure if asp.net can do that. But you could always provide a name like this:
var data= { data: '<data>xxxxx<data>'};
$.post('http://server/service.asmx/test',data,function(){
//callback
},'xml');
Then at the server you can access by the
var data = Request.Params("data");

pass an array in jquery via ajax to a c# webmethod

I'd like to pass an array to a c# webmethod but don't have a good example to follow. Thanks for any assistance.
Here is what I have so far:
My array:
$(".jobRole").each(function (index) {
var jobRoleIndex = index;
var jobRoleID = $(this).attr('id');
var jobRoleName = $(this).text();
var roleInfo = {
"roleIndex": jobRoleIndex,
"roleID": jobRoleID,
"roleName": jobRoleName
};
queryStr = { "roleInfo": roleInfo };
jobRoleArray.push(queryStr);
});
My ajax code
$.ajax({
type: "POST",
url: "WebPage.aspx/save_Role",
data: jobRoleArray,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: function (data) {
alert("successfully posted data");
},
error: function (data) {
alert("failed posted data");
alert(postData);
}
});
Not sure on the webmethod but here is what I'm thinking:
[WebMethod]
public static bool save_Role(String jobRoleArray[])
You will be passing an array of:
[
"roleInfo": {
"roleIndex": jobRoleIndex,
"roleID": jobRoleID,
"roleName": jobRoleName
},
"roleInfo": {
"roleIndex": jobRoleIndex,
"roleID": jobRoleID,
"roleName": jobRoleName
}, ...
]
And in my opinion, it would be easier if you have a class that matches that structure, like this:
public class roleInfo
{
public int roleIndex{get;set;}
public int roleID{get;set;}
public string roleName{get;set;}
}
So that when you call your web method from jQuery, you can do it like this:
$.ajax({
type: "POST",
url: "WebPage.aspx/save_Role",
data: "{'jobRoleArray':"+JSON.stringify(jobRoleArray)+"}",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: function (data) {
alert("successfully posted data");
},
error: function (data) {
alert("failed posted data");
alert(postData);
}
});
And in your web method, you can receive List<roleInfo> in this way:
[WebMethod]
public static bool save_Role(List<roleInfo> jobRoleArray)
{
}
If you try this, please let me know. Above code was not tested in any way so there might be errors but I think this is a good and very clean approach.
I have implement something like this before which is passing an array to web method. Hope this will get you some ideas in solving your problem. My javascript code is as below:-
function PostAccountLists() {
var accountLists = new Array();
$("#participantLists input[id*='chkPresents']:checked").each(function () {
accountLists.push($(this).val());
});
var instanceId = $('#<%= hfInstanceId.ClientID %>').val();
$.ajax({
type: "POST",
url: "/_layouts/TrainingAdministration/SubscriberLists.aspx/SignOff",
data: "{'participantLists': '" + accountLists + "', insId : '" + instanceId + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
AjaxSucceeded(msg);
},
error: AjaxFailed
});
}
In the code behind page (the web method)
[WebMethod]
public static void SignOff(object participantLists, string insId)
{
//subscription row id's
string[] a = participantLists.ToString().Split(',');
List<int> subIds = a.Select(x => int.Parse(x)).ToList<int>();
int instanceId = Convert.ToInt32(insId);
The thing to notice here is in the web method, the parameters that will receive the array from the ajax call is of type object.
Hope this helps.
EDIT:-
according to your web method, you are expecting a value of type boolean. Here how to get it when the ajax call is success
function AjaxSucceeded(result) {
var res = result.d;
if (res != null && res === true) {
alert("succesfully posted data");
}
}
Hope this helps
Adding this for the ones, like MdeVera, that looking for clean way to send array as parameter. You can find the answer in Icarus answer. I just wanted to make it clear:
JSON.stringify(<your array cames here>)
for example, if you would like to call a web page with array as parameter you can use the following approach:
"<URL>?<Parameter name>=" + JSON.stringify(<your array>)

Resources