2010-04-16 38 views
12

Estoy tratando de obtener un ajax para acceder a un método web en código subyacente. El problema es que sigo obteniendo el error "parserror" del método jQuery onfail.JQuery llamada ajax a httpget webmethod (C#) no funciona

Si cambio el GET a un POST todo funciona bien. Por favor vea mi código abajo.

Ajax llamada

<script type="text/javascript"> 
     var id = "li1234"; 

     function AjaxGet() { 
      $.ajax({ 
       type: "GET", 
       url: "webmethods.aspx/AjaxGet", 
       data: "{ 'id' : '" + id + "'}", 
       contentType: "application/json; charset=utf-8", 
       dataType: "json", 
       async: false, 
       success: function(msg) { 
        alert("success"); 

       }, 
       error: function(msg, text) { 
        alert(text); 
       } 
      }); 
     } 

    </script> 

Código Detrás

[System.Web.Services.WebMethod] 
[System.Web.Script.Services.ScriptMethod(UseHttpGet = true, 
    ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)] 
public static string AjaxGet(string id) 
{ 
    return id; 
} 

Web.config

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

La dirección URL que se utiliza

......../webmethods.aspx/AjaxGet {% 20% 27id% 27% 20:% 20% 27% 27li1234}?

Como parte de la respuesta, devuelve el html para los métodos web de la página.

Cualquier ayuda será muy apreciada.

Respuesta

22

Antes de que todo lo que pude decir, que no elige el camino más fácil. ScriptMethods es fácil de usar junto con ASP.NET ScriptManager y no con jQuery. Le recomendaré que utilice mejor los Servicios HTTP WCF habilitados para JSON (mejor como Servicio RESTfull) en lugar del Servicio web ASMX que intenta utilizar ahora. Sin embargo, uno puede hacer que el código funcione sin usar ninguna tecnología de Microsoft en el lado del cliente.

Primero verifique el lado del servidor.

  1. Renombrar webmethods.aspx a webmethods.asmx.
  2. Compruebe que ha colocado el interior de \ y una httpHandlers para la extensión asmx (ScriptHandlerFactory) también existen en la configuración:

    <configuration> 
        <!-- ... --> 
        <system.web> 
        <webServices> 
         <protocols> 
         <add name="HttpGet"/> 
         </protocols> 
        </webServices> 
        <httpHandlers> 
         <!-- ... --> 
         <add verb="*" path="*.asmx" 
          type="System.Web.Script.Services.ScriptHandlerFactory" 
          validate="false"/> 
        </httpHandlers></system.web></configuration> 
    
  3. Verificar que [ScriptService] [atributo (System.Web.Script.Services. ScriptService] si le gustan los nombres completos) establecido para su clase heredada de System.Web.Services.WebService.

Ahora podría probar el servicio.Abrir en que la URL en el navegador Web como http://localhost/webmethods.asmx/AjaxGet?id=li1234 Si recibe de nuevo algo así como
<?xml version="1.0" encoding="utf-8" ?>
<string xmlns="http://tempuri.org/">li1234</string>

Puede estar seguro de que la parte que el servicio funciona bien.

Observación: Independ en “ResponseFormat = System.Web.Script.Services.ResponseFormat.Json” atribuir la respuesta de servicio con las respuestas XML si “Content-Type: application/json;” no se establece en la solicitud.

Ahora arreglaremos el código del cliente. Espero que los comentarios que coloqué en el siguiente código lo expliquen todo.

Una pequeña observación más. En la última parte del código que llamo una más “complejo” método Web:

[WebMethod] 
[ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] 
public OutputData AjaxGetMore (InputData input) { 
    return new OutputData() { 
     id = input.id, 
     message = "it's work!", 
     myInt = input.myInt+1 
    }; 
} 

Dónde

public class OutputData { 
    public string id { get; set; } 
    public string message { get; set; } 
    public int myInt { get; set; } 
} 
public class InputData { 
    public string id { get; set; } 
    public int myInt { get; set; } 
} 

Ahora solamente el código JavaScript que utilizan en algunos lugares JSON plugin, que podría ser sustituido por json2 Crockford .js, si alguien lo prefiere.

var id = "li1234"; 
// version 1 - works 
var idAsJson = '"' + id + '"'; // string serializes in JSON format 
$.ajax({ 
    type: "GET", 
    url: "/webmethods.asmx/AjaxGet?id=" + idAsJson, 
    contentType: "application/json; charset=utf-8", 
    success: function(msg) { 
     alert(msg.d); // var msg = {d: "li1234"} 
    }, 
    error: function(res, status) { 
     if (status ==="error") { 
      // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace 
      var errorMessage = $.parseJSON(res.responseText); 
      alert(errorMessage.Message); 
     } 
    } 
}); 

// version 2 with respect of JSON plugin 
$.ajax({ 
    type: "GET", 
    url: "/webmethods.asmx/AjaxGet?id=" + $.toJSON(id), 
    contentType: "application/json; charset=utf-8", 
    success: function(msg) { 
     alert(msg.d); // var msg = {d: "li1234"} 
    }, 
    error: function(res, status) { 
     if (status ==="error") { 
      // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace 
      var errorMessage = $.parseJSON(res.responseText); 
      alert(errorMessage.Message); 
     } 
    } 
}); 
// version 3 where jQuery will construct URL for us 
$.ajax({ 
    type: "GET", 
    url: "/webmethods.asmx/AjaxGet", 
    data: {id: $.toJSON(id)}, 
    dataType: "json", 
    contentType: "application/json; charset=utf-8", 
    success: function(msg) { 
     alert(msg.d); // var msg = {d: "li1234"} 
    }, 
    error: function(res, status) { 
     if (status ==="error") { 
      // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace 
      var errorMessage = $.parseJSON(res.responseText); 
      alert(errorMessage.Message); 
     } 
    } 
}); 
// version 4. We set "Content-Type: application/json" about our data, but we use no 
//   not 'dataType: "json"' parameter. Then we have "Accept: */*" in the request 
//   instead of "Accept: application/json, text/javascript, */*" before. 
//   Everithing work OK like before. 
$.ajax({ 
    type: "GET", 
    url: "/webmethods.asmx/AjaxGet", 
    data: {id: $.toJSON(id)}, 
    contentType: "application/json; charset=utf-8", 
    success: function(msg) { 
     alert(msg.d); // var msg = {d: "li1234"} 
    }, 
    error: function(res, status) { 
     if (status ==="error") { 
      // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace 
      var errorMessage = $.parseJSON(res.responseText); 
      alert(errorMessage.Message); 
     } 
    } 
}); 
// version 5. If we don't place "Content-Type: application/json" in our reqest we 
//   receive back XML (!!!) response with "HTTP/1.1 200 OK" header and 
//   "Content-Type: text/xml; charset=utf-8" which will be placed. 
//   How one can read in 
// http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx), 
//    ASP.NET AJAX will not make JSON serialized of response data for 
//    security reasons. 
$.ajax({ 
    type: "GET", 
    url: "/webmethods.asmx/AjaxGet", 
    data: {id: $.toJSON(id)}, 
    dataType: "json", 
    //contentType: "application/json; charset=utf-8", 
    success: function(msg) { 
     alert(msg.d); // var msg = {d: "li1234"} 
    }, 
    error: function (res, status, ex) { 
     // the code here will be works because of error in parsing server response 
     if (res.status !== 200) { // if not OK 
      // we receive exception in the next line, be 
      var errorMessage = $.parseJSON(res.responseText); 
      alert(errorMessage.Message); 
     } else { 
      alert("status=" + status + "\nex=" + ex + "\nres.status=" + res.status + "\nres.statusText=" + res.statusText + 
        "\nres.responseText=" + res.responseText); 
     } 
    } 
}); 
// version 6. Send more komplex data to/from the service 
var myData = { id: "li1234", myInt: 100} 
$.ajax({ 
    type: "GET", 
    url: "/webmethods.asmx/AjaxGetMore", 
    data: {input:$.toJSON(myData)}, 
    dataType: "json", 
    contentType: "application/json; charset=utf-8", 
    success: function(msg) { 
     // var msg = {__type: "Testportal.OutputData", id: "li1234", message: "it's work!", myInt:101} 
     alert("message=" + msg.d.message + ", id=" + msg.d.id + ", myInt=" + msg.d.myInt); 
    }, 
    error: function(res, status) { 
     if (status ==="error") { 
      // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace 
      var errorMessage = $.parseJSON(res.responseText); 
      alert(errorMessage.Message); 
     } 
    } 
}); 
+0

Su solución para esto funciona para los servicios web 'asmx', pero ¿es posible hacer esto si el WebMethod está dentro de un archivo' aspx'? –

+0

@MattRoberts: Todo es posible, pero no entiendo completamente la razón de eso. aspx se utilizan para buscapersonas HTML generales o para formularios web. Entonces * se usará el Handler * correspondiente para procesar la solicitud a la URL. Así que el uso de la extensión de archivo es realmente práctico. Puede usar [ASHX] (http://msdn.microsoft.com/en-us/library/bb398986 (v = vs.100) .aspx) para crear identificadores generales que procesan solicitudes HTTP comunes y que no tienen una IU. o marcado de HTML. – Oleg

2
//... 
data: { "id" : id }, 
//... 

Los datos son un objeto, no una cadena que se parece a un objeto.

Si utiliza una cadena, debe ser una cadena con formato correcto de consulta URL, así:

//... 
data: "id=" + encodeURIComponent(id) + "&otherstuff=" + encodeURIComponent(data), 
//... 
+0

Eso tiene sentido. Ahora tengo esta url ...../webmethods.aspx/AjaxGet? Id = li1234 pero todavía está devolviendo el mismo error, "parseerror". –

+0

@Tim: Oh, ya lo veo. El tipo de contenido de su solicitud GET no es JSON. Solo deja ese parámetro por completo. El tipo de respuesta es JSON, por lo que el parámetro dataType está bien. – Tomalak

+0

Gracias, ahora no obtengo un error, aunque no está llegando a mi webmethod aunque está volviendo a la función de éxito. En la respuesta acabo de obtener el html de webwethods. Lamento ser doloroso, por favor ayuda. –

1

También podría retirar http://www.json.org/js.html JSON.stringify donde se acepta un objeto JSON como parámetro y devuelve una cadena.

0

Para aquellos que utilizan VB, adornar su método como este:

<WebMethod()> 
<ScriptMethod(UseHttpGet:= True, ResponseFormat:= ResponseFormat.Json)> 
Cuestiones relacionadas