2012-09-28 15 views
6

Este tema parece ser uno con un millón de "soluciones" con resultados aún más mixtos. Así que, por favor, descanse un poco ya que intentaré demostrar lo que está sucediendo, lo que estoy usando y cómo he intentado resolver el problema.servicio web asmx - jQuery ajax post json (error 500) - CORS (Access-Control-Allow-Origin está establecido en *)

Mi entorno de prueba se está ejecutando IIS6 asp.net 2.0, he configurarlo con

'Access-Control-Allow-Origin' * 

También he creado los verbos para .asmx extensiones a

"GET,HEAD,POST,DEBUG,OPTIONS" 

a través de jQuery v1. 7.2 llamadas ajax() Puedo obtener archivos xml del servidor y POST a un servicio básico que devuelve una cadena con resultados cruzados. Así que SÉ que al menos parcialmente mis solicitudes de dominio cruzado están funcionando.

Mi problema surge cuando comienzo a ampliar ese, y el uso de JSON para enviar datos al servicio

Tengo un método simple asmx servicio web:

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

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

      return sr; 
     } 

magia muy simple, y no mucho sucediendo allí, todo lo que quiero hacer es pasar el objeto 'SubRequestXX', y por ahora simplemente validarlo llegó allí y responder.

Using jQuery: 

    $.ajax({ 
     type: "POST", 
     url: "http://somedomain/subscription/MyService.asmx/HelloWorldX", 
     processData: false, 
     data: '{ "SubReq" : {"EmailAddress":"[email protected]"} }', 
     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); 
     } 
    }); 
} 

Quizás la respuesta está allí? pero esto es lo que los datos RAW del violinista me muestra utilizando el mismo código JS exacta de una página en el mismo dominio (éxito - código de resultado 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":"[email protected]"} } 

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 - [email protected]"}} 

así que todo se ve muy bien y se comporta como se esperaba. Ahora bien, si tomo esa misma html/código JS, desplegar en otro servidor y hacer la misma petición (cross-site) muestra violinista (falla código de resultado 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 

Muchos resultados sugieren un par de Web. cambios de configuración. si añado lo siguiente a mi sección system.web:

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

entonces mi solicitud se parece

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 

y mi respuesta:

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) 

Así añadiendo que la sección de mi web. config hizo algo porque mis resultados son ligeramente diferentes. Pero no puedo discernir qué.

Otras soluciones sugieren estos ajustes de configuración web, ya que estoy utilizando asp.net 2.0, tenga en cuenta lo que me queda éstos como se muestra en todos los resultados anteriores, comentadas son las originales de la creación del proyecto:

 <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> 

Así ... la gran Pregunta ... ¿Por qué mis solicitudes entre sitios están fallando con el mismo código, a pesar de todo lo anterior? Parece que tan pronto como la solicitud proviene de otro dominio se bloquea en JSON.

Cualquier ayuda sería muy apreciada para resolver este misterio. Supongo que es una configuración de IIS6 (servidor) o mi $.ajax() llame y creo que probablemente sea algo simple o pequeño, pero parece que no puedo señalarlo.

Respuesta

0

Probé algo simillar a través de JSONP. Creo que basé la solución en este artículo.

JSONP + CORS

Otra cosa es que el potencial de poner en su JSON como una cadena a un servicio WCF normalmente no termina bien (Sé que esto no es WCF, simplemente diciendo que podría ser el mismo tema). Normalmente hago esto:

Using jQuery: 

$.ajax({ 
    type: "POST", 
    url: "http://somedomain/subscription/MyService.asmx/HelloWorldX", 
    processData: false, 
    data: JSON.parse('{ "SubReq" : {"EmailAddress":"[email protected]"} }'), 
    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); 
    } 
}); 
} 

El uso de JSON.parse también detectará cualquier JSON defectuoso que se produzca.

Espero que esto solucione su problema.

Cuestiones relacionadas