title: Troubleshooting jQuery AJAX call using Generic Handler in ASP.NET
body: <p>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?</p>
  
  <p>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.</p>
  
  <p><strong>Requesting Page JavaScript:</strong></p>
  
  <pre><code>    jQuery("#&lt;%=BtnUCSSearch.ClientID %&gt;").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
  
      });
  </code></pre>
  
  <p><strong>Response Page for AJAX call code behind (AddressSearch.ashx.vb):</strong></p>
  
  <pre><code>Imports System
  Imports System.Web
  Imports System.Web.Services
  Imports System.Web.HttpContext
  
  &lt;WebService([Namespace]:="http://tempuri.org/")&gt; _
  &lt;WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)&gt; _
  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
  </code></pre>
  
  <p>=============================</p>
  
  <h1>1/2/2012 @ 12:49pm update</h1>
  
  <p>Per the two answers, I did a little bit more troubleshooting..</p>
  
  <p>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.</p>
  
  <p><a href="https://localhost/Accessioning/FullDataEntry/AddressSearch.ashx?CompanyName=xxx&amp;PrimaryPhone=555-555-5555&amp;PostalCode=55555" rel="nofollow">https://localhost/Accessioning/FullDataEntry/AddressSearch.ashx?CompanyName=xxx&amp;PrimaryPhone=555-555-5555&amp;PostalCode=55555</a></p>
  
  <p><strong>Response:</strong></p>
  
  <p>{ "responseProperty": "xxxxxxxxx" }</p>
  
  <p>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.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>================</p>
  
  <p>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.</p>
  
  <pre><code>&lt;%@ WebHandler Language="VB" CodeBehind="AddressSearch.ashx.vb" Class="UI.Web.AddressSearch1" %&gt;
  </code></pre>
  
  <p>================</p>
  
  <p>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.  </p>
  
  <p>Also put "var" in front of my JS variables.</p>
  
  <p>We're getting closer.</p>
  
  <pre><code>    jQuery("#&lt;%=BtnUCSSearch.ClientID %&gt;").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;
              }
          }); 
  
      });
  </code></pre>
  
  <p>==========================</p>
  
  <h1>1/2/2012 @ 1:52pm</h1>
  
  <p>code snippet #1 (GET request):</p>
  
  <pre><code>    jQuery("#&lt;%=BtnUCSSearch.ClientID %&gt;").click(function() {
  
          jQuery.get("AddressSearch.ashx", { CompanyName: "xxx", PrimaryPhone: "555", PostalCode: "55555" }, function(data) {
              alert("got here");
              //alert("Data Loaded: " + data.responseProperty);
              return false;
          });
  
      });
  </code></pre>
  
  <p>calling page via request page (for #1):</p>
  
  <p>params: <a href="http://screencast.com/t/oA0i48O5y7" rel="nofollow">http://screencast.com/t/oA0i48O5y7</a></p>
  
  <p>headers: <a href="http://screencast.com/t/3khfRjI7" rel="nofollow">http://screencast.com/t/3khfRjI7</a></p>
  
  <p>response: nothing</p>
  
  <p>calling page via browser directly (for #1):
  <a href="https://localhost/Accessioning/FullDataEntry/AddressSearch.ashx?CompanyName=xxx&amp;PrimaryPhone=555&amp;PostalCode=55555" rel="nofollow">https://localhost/Accessioning/FullDataEntry/AddressSearch.ashx?CompanyName=xxx&amp;PrimaryPhone=555&amp;PostalCode=55555</a>
  response (page output) although console says nothing:
  {"responseProperty":"reponse via SimpleResponse class"}</p>
  
  <p>=====================</p>
  
  <p>code snippet #2 (POST request type):</p>
  
  <pre><code>        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;
              }
          });
  </code></pre>
  
  <p>calling page via request page (for #2):</p>
  
  <p>headers: <a href="http://screencast.com/t/ostM7NKCxT" rel="nofollow">http://screencast.com/t/ostM7NKCxT</a></p>
  
  <p>post: <a href="http://screencast.com/t/VKZdgGuOl" rel="nofollow">http://screencast.com/t/VKZdgGuOl</a></p>
  
  <p>response: <a href="http://screencast.com/t/LP3R8OAm" rel="nofollow">http://screencast.com/t/LP3R8OAm</a></p>
  
  <p>calling page via browser directly (for #2):
  <a href="https://localhost/Accessioning/FullDataEntry/AddressSearch.ashx?CompanyName=xxx&amp;PrimaryPhone=555&amp;PostalCode=55555" rel="nofollow">https://localhost/Accessioning/FullDataEntry/AddressSearch.ashx?CompanyName=xxx&amp;PrimaryPhone=555&amp;PostalCode=55555</a></p>
  
  <p>response (page output) although console says nothing:
  {"responseProperty":"reponse via SimpleResponse class"}</p>
  
  <p>============================</p>
  
  <h1>1/2/2012 @2:48pm</h1>
  
  <p>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.</p>
  
  <pre><code>    jQuery(document).ready(function() {
  
          //jQuery("#form").submit(function() { return false; });
  
          jQuery("#&lt;%=TxtLastName.ClientID %&gt;").focus();
          //jQuery("#&lt;%=PnlUCSSearch.ClientID %&gt;").hide();
  
          // START unassigned collection site address search logic
          jQuery("#&lt;%=DDLCollectionSite.ClientID %&gt;").change(function() {
              //alert("hello world: " + this.value);
              if (this.value != "2") {
                  jQuery("#&lt;%=PnlUCSSearch.ClientID %&gt;").hide();
                  jQuery("#&lt;%=DDLCollectionSite.ClientID %&gt;").focus();
              }
              else {
                  jQuery("#&lt;%=PnlUCSSearch.ClientID %&gt;").show();
                  jQuery("#&lt;%=TxtUCSCompany.ClientID %&gt;").focus();
              }
          });
  
          jQuery("#&lt;%=BtnUCSSearch.ClientID %&gt;").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
  
      });
  </code></pre>