I am currently using AJAX to send a JSON object to a Handler written in C#. I was wondering if I can pass the JSON information through a simple url for debugging purposes, just like when I used to use simple parameters (queries) on URLs.
The C# handler deserializes the JSON into a class based on Name and Pass (strings).
So I am trying to go to the handler on the URL like this:
testHandler.ashx?Name=Hey&Pass=Check
Though the C# handler cannot deserialize that properly and the class object is null, if sent that way.
AJAX code of sending a working request to the web server:
var jsonParam = { Name: "test", Pass: "123" }
$.ajax({
url: "Test.ashx",
type: "post", //This sends in url
data: JSON.stringify(jsonParam),
dataType: "json",
contentType: 'application/json; charset=utf-8',
async:false,
success: function (response) {
alert(response.Name);
}
});
So I am wondering what this would look like, if sent through the browser on the URL text box.
P.S - I don't have a problem, I'm just trying to understand the work behind the serialization.
In the sample code you provided you are using JSON object serialized in the body of a POST request. Then you seem to be talking about some testHandler.ashx?Name=Hey&Pass=Check url where you are illustrating the values being passed as query string parameters. There's no longer JSON involved in this case. You should not be passing JSON payloads as parts of the query string. This is a perfectly valid request that you could achieve with the GET verb:
var jsonParam = { Name: "test", Pass: "123" }
$.ajax({
url: "Test.ashx",
type: "GET",
data: jsonParam,
dataType: "json",
success: function (response) {
alert(response.Name);
}
});
In this case you will obviously retrieve the values directly from the query string of course instead of doing any JSON deserialization in your handler:
public void ProcessRequest(HttpContext context)
{
string name = context.Request["Name"];
string pass = context.Request["Pass"];
context.Response.ContentType = "application/json";
...
}
Oh and by the way notice that I have removed the async: false switch from your code coz everytime I see this it makes me vomit.
Related
I'm tring to pass a value I pull from a data-attribute in my markup to a C# method using jQuery Ajax. In this example, the value for QuestionNumber results in a 1. EMHQQuestion is an enum with values 1 through 15. I expect my C# method DeleteCondition to receive that 1 but instead I get a 500 internal server error: "Invalid web service call, missing value for parameter: 'questionNumber'.
Any suggestions?
function DeleteConditions() {
var QuestionNumber = $('.noRadioButton').data('questionnumber');
$.ajax({
url: "mhqpreinterview.aspx/deletecondition",
type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
questionNumber: QuestionNumber
});
Dialog.dialog('close');
}
..
[WebMethod(EnableSession = true)]
public static void DeleteCondition(EMHQQuestion questionNumber)
{
//stuff
}
I struggled with this EXACT same thing when making AJAX reqs to web form methods.
For your c# method:
[System.Web.Services.WebMethod()]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string DeleteCondition(EMHQQuestion questionNumber)
{
// do enum stuff here
}
Please note that I have changed the method type from void to string. It is a good idea to send some identifiable information back to the client. Even if you do not have to send data back, it gives you a chance to customize success or helpful debugging information.
Here are the changes you have to make to your AJAX object:
var params = '{ questionNumber: ' + JSON.stringify(QuestionNumber) + '}';
var post = {
type: 'POST',
url: 'mhqpreinterview.aspx/deletecondition',
data: params,
contentType: "application/json; charset=utf-8",
dataType: "json"
};
$.ajax(post);
What you should be taking away from the above javascript, is the use of JSON.stringify before you send to your method. You have to make sure QuestionNumber is parameterized correctly and already valid JSON for the web service method to receive.
If you find its still not working, check to see what value is being stored inside QuestionNumber before you are trying to send it.
The above code does work with me, any other troubles post a comment and I will do my best to help answer it.
Use data jquery ajax field:
data: JSON.stringify({QuestionNumber: QuestionNumber}),
dataType: "json",
I have a webMethod with a single argument I am trying to call via jQuery Ajax. Now the argument is supposed to be the query string of the url in which I am making the ajax call. I don't know how to pass the query string as an argument into the method from the jQuery ajax. My Code is as follows
C# Method
[WebMethod]
public static string FollowUser(string userId)
{
//Code to follow user
//returns a string value
}
jQuery Ajax
$(document).ready(function() {
$("#btnFollow").click(function() {
$.ajax({
type: "POST",
url: "Default.aspx/FollowUser",
data: //how do I pass the query string here
contentType: "application/json; charset=utf-8", datatype: "json",
context: this,
success: function(msg) {
//I'm doing some stuff here
}
},
error: function(response) {
alert(response.d);
}
});
});
});
Someone help me out. Thanks.
You need to pass the data as part of the the URL or change the method to GET. When submitting an aJax post with data you are sending the data as part of the request body (form data). This won't be as a query string attribute but part of the content. Instead change the URL To include the data. Example.
Default.aspx/FollowUser?userId=user1
changing to a GET method will force the post parameters to be part of the query string instead.
I got a problem while working with knockoutJs and asp.net c#.
When I passed a json string from page to another popup page using jquery ajax and knockoutJs for printing.
The problem occur:
When the Json string is small. It works fine, the popup page shows string data in table.
However, when the json string is large. It doesn't work anymore. The error occurs with message:
"Uncaught Sys.ArgumentException: Sys.ArgumentException: Cannot deserialize. The data does not correspond to valid JSON.
Parameter name: data"
Here is my code:
$.ajax({
type: "POST",
url: 'InProgressBrief.aspx/PrintReport',
data: ko.toJSON({ reportData: ko.toJSON(InProgressBriefs.Briefs) }),
async: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
window.open("PrintInProgressBrief.aspx?month=" + InProgressBriefs.Month() + "&year=" + InProgressBriefs.Year(), "", "status=0,toolbar=0,width=1000,height=900");
}
})
Here is my webMethod
[WebMethod]
public static void PrintReport(string reportData)
{
PSCDialog.DataShare = reportData;
}
The popup page recieves the Json tring:
if (PSCDialog.DataShare != null)
return PSCDialog.DataShare as string;
In the popup page UI, I set the knockoutjs variable, my UI javascript code is something like follow:
var InProgressBriefs = {
Briefs: ""
;
$(function(){
InProgressBriefs.Briefs = Sys.Serialization.JavaScriptSerializer.deserialize('<%=ReportJSONData%>');
ko.applyBindings(InProgressBriefs, $('#mainDivPrint')[0]);
})
Would anyone please tell me what is the problem here? I will appreciate your help alot.
Thank you in advance.
One thing that's a little suspicious is the line
data: ko.toJSON({ reportData: ko.toJSON(InProgressBriefs.Briefs) }),
When that's deserialized, you wind up with reportData being a JSON-encoded string rather than a native object. I doubt that's what you want. More likely what you need is
data: ko.toJSON({ reportData: ko.toJS(InProgressBriefs.Briefs) }),
which serializes only once.
This is a simplified flow, but it will be easier to explain:
I have an application which calls an webmethod using JQuery, it gets the returning value and stores in a hidden field so this can be accessed by the code behind once a postback is made.
I have the following code:
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ contacts: _contacts }),
dataType: 'json',
url: '/MyPage.aspx/MyMethod',
success: function (result) {
hdn.val(result.d);
}
});
In my code behind I try to get this information and parse it:
protected void btnRegister_Click(object sender, EventArgs e)
{
ContactInfo[] importedContacts = new JavaScriptSerializer().Deserialize<ContactInfo[]>(this.hdContacts.Value);
}
But I get an exception saying:
Value cannot be null. Parameter name: type
I figured out the the problem is this _Type parameter, which doesnt exist in my ContactInfo object.
I am wondering how I can deserialize this information. This should be easily deserializable because it comes directly from my ajax call.
Edit: about the "type" parameter: it is added automatically by the .NET Framework in order to serialize the return object for the WebMethod MyPage.aspx/MyMethod. I imagined that if the framework adds this information when serializing the data, I could use the same serializer to deserialize it....
In the hdnValue I have the following string:
[{"__type":"Un.Socialize.ContactInfo","ID":"123","FirstName":"First","LastName":"Last","FullName":"First Last","EMail":"email#email.com","Nickname":"Nick","Picture":"Pic.jpg","AlreadyExists":false}]
If I (during debug) remove the "__type:..." parameter, it works.
Reading this article I noticed that the problem was not on the webmetho response, but on my deserialization. I shouldn't try to do that.
Because I have some old code there, I will have to find an workaround, maybe storing the values in the hdnField and building the objects in my server side.
Best way is to do unit testing.
Please give the string "data: JSON.stringify({ contacts: _contacts })"
and also the structure of the your ContactInfo object. If possible sniff the request in Chrome Developer Tool, or Firebug, and give the complete HTTP post request. Then we can find the solution immediately.
What happens is, that your ContactInfo has a _Type field, that can't be null, and your provided data (via jQuery/JSON/AJAX/...) does not have a _Type field.
So either you have to adapt your ContactInfo or your JSON Data, could be as easy as
function AddTypeToContacts(contacts) {
var mangledcontacts=new Array();
for (var i=0;i<contacts.Length;i++) {
var c=contacts[i];
if (!c._Type) c._Type='whatever';
mangledcontacts[mangledcontacts.Length]=c;
}
return mangledcontacts;
}
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ contacts: AddTypeToContacts(contacts) }),
dataType: 'json',
url: '/MyPage.aspx/MyMethod',
success: function (result) {
hdn.val(result.d);
}
});
Simply put I want to call public static methods decorated with WebMethod attribute inside my code-behind C# file from jquery.ajax to get some json and other simple stuff (in different functions). But instead I'm getting whole page :'(
I'm not using asp.net AJAX though I'm developing for .NET 3.5 framework and using VS 2008. (There are some restrictions from client)
Please let me know if I can use page-methods with using asp.net ajax or If not what is other simple solution?
After much deliberations I found the problem. I was using jquery's editable plugin. This was source of the problem. When jeditable calls jquery's ajax it sets ajax options like this:
var ajaxoptions = {
type: 'POST',
data: submitdata,
url: settings.target,
success: function(result, status) {
if (ajaxoptions.dataType == 'html') {
$(self).html(result);
}
self.editing = false;
callback.apply(self, [result, settings]);
if (!$.trim($(self).html())) {
$(self).html(settings.placeholder);
}
},
error: function(xhr, status, error) {
onerror.apply(form, [settings, self, xhr]);
}
};
so it was sending the things as simple html and to use this with page methods we need to setup the things so that it sends as json. So we need to add something to the settings like this:
var ajaxoptions = {
type: 'POST',
data: submitdata,
url: settings.target,
dataType: 'json', //Data Type
contentType: 'application/json; charset=utf-8', //Content Type
//....other settings
};
So I put two new properties in settings dataType and contentType and changed above to this:
var ajaxoptions = {
type: 'POST',
data: submitdata,
url: settings.target,
dataType: settings.dataType,
contentType: settings.contentType,
//....other settings
};
Now another problem arised :( it was sending data (from submitdata property) as normal query-string which asp.net does not accept with json requests. So I had to use jquery's json plugin and change the way data is sent in ajax using following test on dataType:
if (settings.dataType == "json") {
if ($.toJSON) {
submitdata = $.toJSON(submitdata);
}
}
and it works like breeze!!!
Russ Cam posted this link in response to another question (so if this helps, go up vote his answer ;)):
Using jQuery to directly call ASP.NET AJAX Page Methods
Dave Ward has a series of posts that use jQuery directly with ASP.Net PageMethods, no MS Ajax UpdatePanel required. In particular this post will get you started.
I am not sure but i think WebMethods are accessible only through asp.net AJAX. I may be wrong though, because we dont use it that way at all. We do it in a slightly different way.
We have built a aspx page which accepts all our AJAX requests and passes them to the subsequent methods.
Server side code
If Not (Request("method") Is Nothing) Then
method = Request("method")
username = HttpContext.Current.User.Identity.Name.ToString
Select Case UCase(method)
Case "GETPROJECTS"
Response.ContentType = "text/json"
Response.Write(GetProjects(Request("cid"), Request("status")))
Exit Select
end select
end if
Client Side code [using jquery]
$.ajaxSetup({
error: function(xhr, msg) { alert(xhr, msg) },
type: "POST",
url: "Ajax.aspx",
beforeSend: function() { showLoader(el); },
data: { method: 'GetProjects', cid: "2", status:"open"},
success: function(msg) {
var data = JSON.parse(msg);
alert(data.Message);
},
complete: function() { hideLoader(el); }
});
Hope this helps.