What is the best method to troubleshooting a jQuery AJAX call with ASP.NET? The error function is getting called--I get the alert to popup that says "Error", but I don't know why. When I attach to my process (w3wp.exe), and place a breakpoint into the code behind of my generic handler ProcessRequest method, it doesn't stop there. So it's not even reaching the handler. Why would that be?
It's also only executing the error function every other click on my search button (BtnUCSSearch). And I don't have an option to press okay on the Error popup like a typical JavaScript alert. It flickers and goes away. I tried putting in a return false to prevent a full page postback, but that didn't seem to work.
Requesting Page JavaScript:
jQuery("#<%=BtnUCSSearch.ClientID %>").click(function() {
urlToHandler = '/Accessioning/FullDataEntry/AddressSearch.ashx';
// hard coding input values for now
jsonData = '{ "CompanyName":"xxx", "PrimaryPhone":"555-555-5555", "PostalCode":"55555" }';
jQuery.ajax({
url: urlToHandler,
data: jsonData,
dataType: 'json',
type: 'POST',
contentType: 'application/json',
success: function(data) {
alert(data.UCSAddress);
},
error: function(data, status, jqXHR) {
alert('Error');
}
}); // end jQuery.ajax
});
Response Page for AJAX call code behind (AddressSearch.ashx.vb):
Imports System
Imports System.Web
Imports System.Web.Services
Imports System.Web.HttpContext
<WebService([Namespace]:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
Public Class AddressSearch
Implements System.Web.IHttpHandler
Implements System.Web.SessionState.IReadOnlySessionState
ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
Public Sub ProcessRequest(ByVal context As HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
context.Response.ContentType = "application/json"
Dim companyName As String = DirectCast(HttpContext.Current.Request.Form("CompanyName"), String)
Dim primaryPhone As String = DirectCast(HttpContext.Current.Request.Form("PrimaryPhone"), String)
Dim postalCode As String = DirectCast(HttpContext.Current.Request.Form("PostalCode"), String)
Dim json As String = "{ ""UCSAddress"": ""xxxxxxxxx"" }"
context.Response.Write(json)
End Sub
End Class
=============================
1/2/2012 @ 12:49pm update
Per the two answers, I did a little bit more troubleshooting..
The way I was retrieving the query string parameters didn't seem to work by using Form. So I'm now using QueryString instead. The page was still returning the JSON object correctly. But at least my query string parameters should work now. However, in this exercise, I explicitly called my generic handler directly from the browser--not via my jQuery.ajax call. So I know the page works well now.
Response:
{ "responseProperty": "xxxxxxxxx" }
Note, I did both methods.. even the approach Mr. Duarte suggested (JavaScriptSerializer). They both work the same.. just a little bit different architecture. Notice I had to create a custom class called SimpleResponse.
Public Sub ProcessRequest(ByVal context As HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
' architecture #1 without JavaScriptSerializer (works)
context.Response.ContentType = "application/json"
Dim companyName As String = DirectCast(HttpContext.Current.Request.QueryString("CompanyName"), String)
Dim primaryPhone As String = DirectCast(HttpContext.Current.Request.QueryString("PrimaryPhone"), String)
Dim postalCode As String = DirectCast(HttpContext.Current.Request.QueryString("PostalCode"), String)
Dim json As String = "{ ""responseProperty"": ""xxxxxxxxx"" }"
context.Response.Write(json)
' architecture #2 with JavaScriptSerializer and SimpleResponse class (also works)
'context.Response.ContentType = "application/json"
'Dim json As JavaScriptSerializer = New JavaScriptSerializer()
'context.Response.Write(json.Serialize(New SimpleResponse()))
'http://codereview.stackexchange.com/questions/3208/basic-simple-asp-net-jquery-json-example
End Sub
Public Class SimpleResponse
Public Property responseProperty() As String
Get
Return _responseProperty
End Get
Set(ByVal value As String)
_responseProperty = value
End Set
End Property
Private _responseProperty As String
Public Sub New()
_responseProperty = "reponse via SimpleResponse class"
End Sub
End Class
================
I also tried wrapping my jsonData with JSON.stringify.. I'm still getting the error. Originally, the jQuery wasn't even calling the page because the class name on the handler had a "1" at the end. When I created the generic handler, it appended a "1" because I already had a page and code behind class named AddressSearch.aspx. I've since fixed that. I had to search for "AddressSearch1" because I couldn't directly edit the file by double clicking it in Solution Explorer.
<%@ WebHandler Language="VB" CodeBehind="AddressSearch.ashx.vb" Class="UI.Web.AddressSearch1" %>
================
Now it's at least calling my code behind, but it's not passing the query string parameters with the data I set in jsonData (that I also stringify'ed). It's also still throwing the errors.
Also put "var" in front of my JS variables.
We're getting closer.
jQuery("#<%=BtnUCSSearch.ClientID %>").click(function() {
var urlToHandler = 'AddressSearch.ashx';
//var urlToHandler = '~/Accessioning/FullDataEntry/AddressSearch.ashx';
//urlToHandler = '/Accessioning/FullDataEntry/AddressSearch.ashx';
// hard coding input values for now
var jsonData = '{ CompanyName:"xxx", PrimaryPhone:"555-555-5555", PostalCode:"55555" }';
//var jsonData = [{ CompanyName: "xxx", PrimaryPhone: "555-555-5555", PostalCode: "55555"}];
jQuery.ajax({
url: urlToHandler,
data: JSON.stringify(jsonData),
dataType: 'json',
type: 'POST',
contentType: 'application/json',
success: function(data) {
//alert("got here");
alert(data.responseProperty);
console.log(" .. response :" + data);
return false;
},
error: function(data, status, jqXHR) {
alert('Error');
//console.log("error :" + XMLHttpRequest.responseText);
//console.log(" .. error :" + data.responseText);
console.log(" .. error");
return false;
}
});
});
==========================
1/2/2012 @ 1:52pm
code snippet #1 (GET request):
jQuery("#<%=BtnUCSSearch.ClientID %>").click(function() {
jQuery.get("AddressSearch.ashx", { CompanyName: "xxx", PrimaryPhone: "555", PostalCode: "55555" }, function(data) {
alert("got here");
//alert("Data Loaded: " + data.responseProperty);
return false;
});
});
calling page via request page (for #1):
params: http://screencast.com/t/oA0i48O5y7
headers: http://screencast.com/t/3khfRjI7
response: nothing
calling page via browser directly (for #1): https://localhost/Accessioning/FullDataEntry/AddressSearch.ashx?CompanyName=xxx&PrimaryPhone=555&PostalCode=55555 response (page output) although console says nothing: {"responseProperty":"reponse via SimpleResponse class"}
=====================
code snippet #2 (POST request type):
var urlToHandler = 'AddressSearch.ashx';
var jsonData = '{ CompanyName:"xxx", PrimaryPhone:"555-555-5555", PostalCode:"55555" }';
jQuery.ajax({
url: urlToHandler,
data: JSON.stringify(jsonData),
dataType: 'json',
type: 'POST',
contentType: 'application/json',
success: function(data) {
if (data != null) {
alert(data.responseProperty);
console.log(" .. response :" + data);
}
return false;
},
error: function(data, status, jqXHR) {
if (data != null) {
alert("Error: " + data.responseText);
console.log(" .. error :" + data.responseText);
}
alert("error occurred");
return false;
}
});
calling page via request page (for #2):
headers: http://screencast.com/t/ostM7NKCxT
post: http://screencast.com/t/VKZdgGuOl
response: http://screencast.com/t/LP3R8OAm
calling page via browser directly (for #2): https://localhost/Accessioning/FullDataEntry/AddressSearch.ashx?CompanyName=xxx&PrimaryPhone=555&PostalCode=55555
response (page output) although console says nothing: {"responseProperty":"reponse via SimpleResponse class"}
============================
1/2/2012 @2:48pm
Final code. Notice the e.preventDefault() and this line of code to prevent that mysterious error. Both were the remaining issues: jQuery("#form").submit(function() { return false; }); Although with the e.preventDefault() call, you don't need the other line. So I commented it out.
jQuery(document).ready(function() {
//jQuery("#form").submit(function() { return false; });
jQuery("#<%=TxtLastName.ClientID %>").focus();
//jQuery("#<%=PnlUCSSearch.ClientID %>").hide();
// START unassigned collection site address search logic
jQuery("#<%=DDLCollectionSite.ClientID %>").change(function() {
//alert("hello world: " + this.value);
if (this.value != "2") {
jQuery("#<%=PnlUCSSearch.ClientID %>").hide();
jQuery("#<%=DDLCollectionSite.ClientID %>").focus();
}
else {
jQuery("#<%=PnlUCSSearch.ClientID %>").show();
jQuery("#<%=TxtUCSCompany.ClientID %>").focus();
}
});
jQuery("#<%=BtnUCSSearch.ClientID %>").click(function(e) {
// jQuery.get("AddressSearch.ashx", { CompanyName: "xxx", PrimaryPhone: "555", PostalCode: "55555" }, function(data) {
// alert("Data Loaded: " + data.responseProperty);
// return false;
// });
var urlToHandler = 'AddressSearch.ashx';
//var urlToHandler = '~/Accessioning/FullDataEntry/AddressSearch.ashx';
//urlToHandler = '/Accessioning/FullDataEntry/AddressSearch.ashx';
// hard coding input values for now
var jsonData = '{ CompanyName:"xxx", PrimaryPhone:"555-555-5555", PostalCode:"55555" }';
//var jsonData = [{ CompanyName: "xxx", PrimaryPhone: "555-555-5555", PostalCode: "55555"}];
jQuery.ajax({
url: urlToHandler,
data: JSON.stringify(jsonData),
dataType: 'json',
type: 'POST',
contentType: 'application/json',
success: function(data) {
if (data != null) {
alert(data.responseProperty);
console.log(" .. response :" + data);
}
},
error: function(data, status, jqXHR) {
//if (data != null) {
// alert("Error: " + data.responseText);
// console.log(" .. error :" + data.responseText);
//}
//alert("error occurred");
}
});
e.preventDefault();
});
// END unassigned collection site address search logic
});