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.