6

This topic seems to be one with a million "solutions" with even more mixed results. So please cut me a little slack as I will try to demonstrate what is going on, what I'm using and how I've attempted to solve the issue.

My testing environment is running IIS6 asp.net 2.0, I have set it up with

'Access-Control-Allow-Origin' *

I have also set the verbs for .asmx extensions to

"GET,HEAD,POST,DEBUG,OPTIONS"

via jQuery v1.7.2 ajax() calls I am able to GET xml files from the sever, and POST to a basic service that returns a string with expected results cross domain. So I KNOW at least partially my cross-domain requests are working.

My issue arises when I start to expand on that, and use json to post data to the service

I have a simple asmx webservice method:

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public SubResponse HelloWorldX(SubRequestXX SubReq)
        {
            SubResponse sr = new SubResponse();

            sr.resultCode = "777";
            sr.resultMsg = "hello - " + SubReq.EmailAddress;

            return sr;
        }

Very simple, and not much magic happening there, all I want to do is pass 'SubRequestXX' object in, and for now simply validate it got there and respond.

Using jQuery:

    $.ajax({
        type: "POST",
        url: "http://somedomain/subscription/MyService.asmx/HelloWorldX",
        processData: false,
        data: '{ "SubReq" : {"EmailAddress":"user@test.com"} }',
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        cache: false,
        success: function(data, textStatus, jqXHR) {
            ajaxSucccess3(data, textStatus, jqXHR);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log("Retrieve Hello Failed (AJAX Error): " + jqXHR.statusText + " | " + textStatus + " | " + errorThrown);
        }
    });
}

Perhaps the answer lies there? but here's what fiddler's RAW data shows me using the exact same JS code from a page on the same domain (success - result code 200):

REQUEST:
    POST http://somedomain/subscription/Service.asmx/HelloWorldX HTTP/1.1
    Accept: application/json, text/javascript, */*; q=0.01
    Content-Type: application/json; charset=utf-8
    X-Requested-With: XMLHttpRequest
    Referer: http://somedomain/subscription/subscription_-cors.html
    Accept-Language: en-us
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; 9LA)
    Host: somedomain
    Content-Length: 45
    Connection: Keep-Alive
    Pragma: no-cache

    { "SubReq" : {"EmailAddress":"user@test.ca"} }

RESPONSE:

    HTTP/1.1 200 OK
    Date: Fri, 28 Sep 2012 16:59:15 GMT
    Server: Microsoft-IIS/6.0
    X-Powered-By: ASP.NET
    Access-Control-Allow-Origin: *
    X-AspNet-Version: 2.0.50727
    Cache-Control: private, max-age=0
    Content-Type: application/json; charset=utf-8
    Content-Length: 147

    {"d":{"__type":"SubService.DataObj.SubResponse","resultCode":"777","resultMsg":"hello - rob@test.ca"}}

So Everything looks great and behaves as expected. Now if I take that same html/js code, deploy on another server and make the same request (cross-site) fiddler shows (fails result code 500):

REQUEST:
    POST http://somedomain/subscription/Service.asmx/HelloWorldX HTTP/1.1
    Accept: */*
    Origin: http://www.crossdomainsite.com
    Accept-Language: en-US
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; 9LA)
    Host: somedomain
    Content-Length: 0
    Connection: Keep-Alive
    Pragma: no-cache


RESPONSE:
HTTP/1.1 500 Internal Server Error
Date: Fri, 28 Sep 2012 16:58:56 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 4732

.....

Request format is unrecognized for URL unexpectedly ending in '/HelloWorldX'

.....

[InvalidOperationException: Request format is unrecognized for URL unexpectedly ending in '/HelloWorldX'.]
   System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +405961
   System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context, String verb, String url, String filePath) +212
   System.Web.Script.Services.ScriptHandlerFactory.GetHandler(HttpContext context, String requestType, String url, String pathTranslated) +47
   System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig) +193
   System.Web.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +93
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Many search results suggest a couple of web.config changes. if I add the following to my system.web section:

    <webServices>
        <protocols>
            <add name="HttpGet"/>
            <add name="HttpPost"/>
        </protocols>
    </webServices>

then my request looks like

POST http://somedomain/subscription/Service.asmx/HelloWorldX HTTP/1.1
Accept: */*
Origin: http://www.crossdomainsite.ca
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; 9LA)
Host: somedomain
Content-Length: 0
Connection: Keep-Alive
Pragma: no-cache

And my RESPONSE:

HTTP/1.1 500 Internal Server Error
Date: Fri, 28 Sep 2012 17:37:00 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Content-Length: 461

System.InvalidOperationException: HelloWorldX Web Service method name is not valid.
   at System.Web.Services.Protocols.HttpServerProtocol.Initialize()
   at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response)
   at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

So adding that section to my web.config did something since my results are slightly different. But I am unable to discern what.

Other solutions suggest these web config settings since I am using asp.net 2.0, note I have left these as shown during all the above results, commented out ones are originals from project creation:

        <httpHandlers>
            <remove verb="*" path="*.asmx"/>
            <!--<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>-->
            <add path="*.asmx" verb="*" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

            <!--<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>-->
            <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

            <!--<add verb="GET,HEAD" path="ScriptResource.axd" validate="false" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>-->
            <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>
        </httpHandlers>

So... the big Question... Why are my cross-site requests failing with the same code, despite all the above? Seems like as soon as the request comes from another domain it chokes on JSON.

Any help would be greatly appreciated solving this mystery. I assume its either a IIS6 (server) setting or my $.ajax() call and I feel like its probably something simple or small, but I can't seem to put my finger on it.

Betard Fooser
  • 526
  • 5
  • 14

1 Answers1

0

I tried something simillar via JSONP. I think I based the solution off this article.

JSONP + CORS

Another potential thing is that putting in your JSON as a string to a WCF service typically does not end well (I know this is not WCF, just saying it could be the same issue). I usually do this:

Using jQuery:

$.ajax({
    type: "POST",
    url: "http://somedomain/subscription/MyService.asmx/HelloWorldX",
    processData: false,
    data: JSON.parse('{ "SubReq" : {"EmailAddress":"user@test.com"} }'),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    cache: false,
    success: function(data, textStatus, jqXHR) {
        ajaxSucccess3(data, textStatus, jqXHR);
    },
    error: function(jqXHR, textStatus, errorThrown) {
        console.log("Retrieve Hello Failed (AJAX Error): " + jqXHR.statusText + " | " + textStatus + " | " + errorThrown);
    }
});
}

The use of JSON.parse will also catch any bad JSON that goes through.

Hope this will fix your issue.

Community
  • 1
  • 1
Benjamin Wong
  • 599
  • 1
  • 8
  • 21