2009-07-17 20 views
19

He estado trabajando en esto durante 3 horas y me he dado por vencido. simplemente estoy tratando de enviar datos a un método web asp.net, usando jQuery. Los datos son básicamente un conjunto de pares clave/valor. así que traté de crear una matriz y agregar los pares a esa matriz.enviando objeto JSON con éxito a asp.net WebMethod, usando jQuery

Mis WebMethod (aspx.cs) tiene el siguiente aspecto (esto puede ser malo para lo que estoy construyendo en javascript, ya no sé):

[WebMethod] 
    public static string SaveRecord(List<object> items) 
    ..... 

Aquí es mi muestra javascript:

var items = new Array;

var data1 = { compId: "1", formId: "531" }; 
    var data2 = { compId: "2", formId: "77" }; 
    var data3 = { compId: "3", formId: "99" }; 
    var data4 = { status: "2", statusId: "8" }; 
    var data5 = { name: "Value", value: "myValue" }; 

    items[0] = data1; 
    items[1] = data2; 
    items[2] = data3; 
    items[3] = data4; 
    items[4] = data5; 
Here is my jQuery ajax call: 

var options = { 
     error: function(msg) { 
      alert(msg.d); 
     }, 
     type: "POST", 
     url: "PackageList.aspx/SaveRecord", 
     data: { 'items': items }, 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     async: false, 
     success: function(response) { 
      var results = response.d; 
     } 
    }; 
    jQuery.ajax(options); 

consigo el error - Invalid JSON primitive: items. -

así que ... si hago esto:

var DTO = { 'items': items };

y establecer el parámetro de datos de la siguiente manera:

data: JSON.stringify(DTO)

entonces me sale este error:

Cannot convert object of type \u0027System.String\u0027 to type \u0027System.Collections.Generic.List`1[System.Object]\u0027 
+0

Cambie su método web para aceptar un Objeto antiguo simple, luego observe exactamente qué es el objeto y moldee y procese en el método web. –

+0

Pregunta, sin embargo, está utilizando métodos web, pero no está utilizando la clase proxy de JavaScript que se genera automáticamente para usted? –

+0

gracias Cory, cambié inicialmente el método web para aceptar un objeto simple, lo que me ayudó a descubrir qué esperar. ¡Gracias! – 29er

Respuesta

8

Cuando uso AJAX.NET, siempre hago que el parámetro de entrada sea simplemente un objeto antiguo y luego uso el deserializador de javascript para convertirlo al tipo que desee. Al menos de esa manera puede depurar y ver qué tipo de objeto está recibiendo el método web.

es necesario convertir el objeto a una cadena cuando se utiliza jQuery

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" > 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
     <asp:ScriptManager ID="sm" runat="server" EnablePageMethods="true"> 
      <Scripts> 
       <asp:ScriptReference Path="~/js/jquery.js" /> 
      </Scripts> 
     </asp:ScriptManager> 
     <div></div> 
    </form> 
</body> 
</html> 
<script type="text/javascript" language="javascript"> 
    var items = [{ compId: "1", formId: "531" }, 
     { compId: "2", formId: "77" }, 
     { compId: "3", formId: "99" }, 
     { status: "2", statusId: "8" }, 
     { name: "Value", value: "myValue"}]; 

     //Using Ajax.Net Method 
     PageMethods.SubmitItems(items, 
      function(response) { var results = response.d; }, 
      function(msg) { alert(msg.d) }, 
      null); 

     //using jQuery ajax Method 
     var options = { error: function(msg) { alert(msg.d); }, 
         type: "POST", url: "WebForm1.aspx/SubmitItems", 
         data: {"items":items.toString()}, // array to string fixes it * 
         contentType: "application/json; charset=utf-8", 
         dataType: "json", 
         async: false, 
         success: function(response) { var results = response.d; } }; 
     jQuery.ajax(options); 
</script> 

Y el código detrás

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Services; 
using System.Web.Script.Serialization; 
using System.Web.Script.Services; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace CustomEquip 
{ 
    [ScriptService] 
    public partial class WebForm1 : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 

     } 
     [WebMethod] 
     public static void SubmitItems(object items) 
     { 
      //break point here 
      List<object> lstItems = new JavaScriptSerializer().ConvertToType<List<object>>(items); 
     } 
    } 
} 
+0

Kenneth, Acabo de probar la versión de jquery exactamente como la codificaste arriba y aún recibí el error: Primitiva JSON inválida: elementos. "Mensaje": "Primitiva JSON inválida: elemento.", "StackTrace": "en System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject() \ r \ n en ..... algo sigue estando mal con eso ¡array, pero no puede resolverlo! – 29er

+0

Kenneth, Probé su versión de PageMethods y funcionó bien. Muchas gracias. Puede que siga esta ruta si no puedo encontrar la solución jQuery. Muy apreciada. – 29er

+0

I Espero que el cambio de objeto sea solo una herramienta de depuración ... hasta que obtenga las conversiones JSON funcionando correctamente. –

3

Decora tu [WebMethod] con otro atributo:

[ScriptMethod(ResponseFormat = ResponseFormat.Json)] 

Creo que esto está en System.Web.Services.Scripting ...

+5

Creo que el problema no es que el servidor no pueda enviar JSON al cliente, el problema es que el servidor no puede deserializar el JSON entrante. – SolutionYogi

46

En su ejemplo, que debería funcionar si su parámetro de datos es:

data: "{'items':" + JSON.stringify(items) + "}" 

Tenga en cuenta que debe enviar un JSON cadena a ASP.NET AJAX. Si especifica un objeto JSON real como parámetro de datos de jQuery, lo serializará como & k = v? K = pares v en su lugar.

Parece que ya lo ha leído, pero eche un vistazo a mi example of using a JavaScript DTO with jQuery, JSON.stringify, and ASP.NET AJAX. Cubre todo lo que necesita para que esto funcione.

Nota: Nunca debe usar JavaScriptSerializer para deserializar manualmente JSON en un "ScriptService" (como lo sugirió alguien más). Automáticamente lo hace por usted, según los tipos de parámetros especificados para su método. Si te encuentras haciendo eso, lo estás haciendo mal.

+0

gracias Dave, simple y completo –

5

El siguiente es un fragmento de código de nuestro proyecto - que tenía problemas con no envolver el objeto como una cadena y también con valores de fecha - espero que esto ayude a alguien:

 // our JSON data has to be a STRING - need to send a JSON string to ASP.NET AJAX. 
     // if we specify an actual JSON object as jQuery's data parameter, it will serialize it as ?k=v&k=v pairs instead 
     // we must also wrap the object we are sending with the name of the parameter on the server side – in this case, "invoiceLine" 
     var jsonString = "{\"invoiceLine\":" + JSON.stringify(selectedInvoiceLine) + "}"; 

     // reformat the Date values so they are deserialized properly by ASP.NET JSON Deserializer    
     jsonString = jsonString.replace(/\/Date\((-?[0-9]+)\)\//g, "\\/Date($1)\\/"); 

     $.ajax({ 
      type: "POST", 
      url: "InvoiceDetails.aspx/SaveInvoiceLineItem", 
      data: jsonString, 
      contentType: "application/json; charset=utf-8", 
      dataType: "json" 
     }); 

la firma del método del servidor tiene el siguiente aspecto:

[WebMethod] 
    public static void SaveInvoiceLineItem(InvoiceLineBO invoiceLine) 
    { 
0

ésta es la forma de definir sus datos (JSON)

data: { 'items': items }, 

y el este de la manera que debe ser

data: '{ items: " '+items +' "}', 

, básicamente, que se serializar el parámetro.

Cuestiones relacionadas