Troubleshooting jQuery AJAX call using Generic Handler in ASP.NET

二次信任 提交于 2019-11-30 18:11:20

问题


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.

https://localhost/Accessioning/FullDataEntry/AddressSearch.ashx?CompanyName=xxx&PrimaryPhone=555-555-5555&PostalCode=55555

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

    });

回答1:


I tried putting in a return false to prevent a full page postback, but that didn't seem to work.

If the main problem is that clicking the button control causes a full post back instead of an asynchronous call to your handler, you can add this code anywhere inside your jQuery click event handler:

jQuery("#<%=BtnUCSSearch.ClientID %>").click(function(e) {
    // Existing code
    e.preventDefault();
})

This works rather than return false to stop the browser's normal behavior for the button click.




回答2:


Inspect the browsers console for more details and set breakpoints in your callbacks (success, error)




回答3:


first of all, take care with global variables in javascript, if is possible abandon this pratice.

Make sure requisition URL is correct and not return 404 error.

In jquery ajax data, use JSON.stringify().

And in the asp.net handler use the JavascriptSerializer.

If not work, run with the firebug console opened, or chrome console. It's very helpful!



来源:https://stackoverflow.com/questions/8703317/troubleshooting-jquery-ajax-call-using-generic-handler-in-asp-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!