2010-01-14 26 views
11

Tengo un contrato de operación que acepta un objeto complejo y estoy llamando a la operación a través de jQuery. ¿Cómo paso un objeto de tipo complejo como ese usando jQuery? A continuación se muestra la firma operación:Pasar objetos complejos a un WCF Rest Service

public Resolution CreateNewResolution(Resolution NewResolution); 

que necesito para pasar en un objeto de la Resolución en el cliente, pero no sé cómo hacer algo como el uso de jQuery. ¿Alguna ayuda?

Gracias

Respuesta

22

Descubre Denny's post para empezar, aunque no estoy de acuerdo con su uso de GET, y pasando JSON en la cadena de consulta para los parametros complejas. Eso parece realmente mal.


El parámetro se utiliza para data es la representación JSON de cualquiera que sea su tipo de resolución es. Por ejemplo, supongamos que el tipo y la operación se define como este en el lado del servidor:

[DataContract(Namespace = "urn:brandon.michael.hunter/ws/2010/01", 
       Name = "Resolution")] 
public class Resolution 
{ 
    [DataMember(IsRequired = true, Name = "Name")] 
    public string Name  { get; set; } 

    [DataMember(IsRequired = true, Name = "Rank")] 
    public int Rank { get; set; } 

    [DataMember(IsRequired = true, Name = "SerialNumber")] 
    public int SerialNumber { get; set; } 

    [DataMember(IsRequired = false, Name = "Id")] 
    public int Id { get; set; } 
} 

[OperationContract] 
[WebInvoke(Method = "PUT", 
      RequestFormat=WebMessageFormat.Json, 
      ResponseFormat = WebMessageFormat.Json, 
      UriTemplate = "new")] 
public Resolution CreateNewResolution(Resolution r) 
{ 
    // your logic here 
    r.Id = System.Guid.NewGuid(); 
    return r; 
} 

Luego, en Javascript, el código que utiliza podría tener este aspecto:

var resolution = {r: { Name : "Fred", Rank : 2, SerialNumber : 17268 }}; 

// convert object to JSON string (See http://jollytoad.googlepages.com/json.js) 
var objectAsJson = $.toJSON(resolution); 
// result is a string: '{"Name":"Fred","Rank":"2","SerialNumber":"17268"}' 

$.ajax({ 
    type  : "PUT",    // must match Method in WebInvoke 
    contentType : "application/json", 
    url   : "Service.svc/new", // must match UriTemplate in WebInvoke 
    data  : objectAsJson, 
    dataFilter : function (data, type) { 
     // convert from "\/Date(nnnn)\/" to "new Date(nnnn)" 
     return data.replace(/"\\\/(Date\([0-9-]+\))\\\/"/gi, 'new $1'); 
    }, 
    processData : false,    // do not convert outbound data to string (already done) 
    success  : function(msg){ ... }, 
    error  : function(xhr, textStatus, errorThrown){ ... } 
}); 

Notas:

  • Debe tener el nombre de la variable (r) para ser el primer objeto en el JSON que se pasa, al menos con WCF 4. Cuando utilicé el anterior Por ejemplo, no funcionó hasta que puse el nombre de la variable al principio.
  • Para pasar objetos complejos en JSON, use PUT o POST como el tipo (Método HTTP) de la solicitud
  • que necesita para convertir el objeto complejo en una cadena JSON. Hay a nice, tiny jquery plugin to do this. Denny proporciona su propia implementación.
  • Encontré que si uso processData=true, la cadena resultante enviada al servicio está en formato querystring, no en JSON. No es lo que quiero para pasar objetos complejos. Entonces lo configuré en falso. Usar "true" estaría bien para solicitudes más sencillas que no sean JSON donde estés haciendo WebGet, y todos los parámetros están en la cadena de consulta.
  • el dataFilter permite la deserialización correcta de los objetos DateTime
  • El parámetro para 0mpasado a la devolución exitosa contiene el json devuelto.
  • Es posible que desee utilizar un reescritura de URL para ocultar esa etiqueta .svc en la URL de solicitud
  • en este caso, el servicio WCF utiliza el comportamiento webHttp, no enableWebScript. Este último genera dinámicamente proxies Javascript para invocar el servicio, pero la forma en que hiciste la pregunta hace que parezca que no quieres eso.

+1

¿Actualizarías esto para mostrar POST en lugar de PUT? POST generalmente se acepta como la forma más segura de evitar travesuras en sitios cruzados – LamonteCristo

0

un vistazo al blog de Gil Fink con respecto a la combinación de WCF Data Services, JSONP y jQuery

http://blogs.microsoft.co.il/blogs/gilf/archive/2011/04/24/combining-wcf-data-services-jsonp-and-jquery.aspx

Durante Mike Flasko de session en MIX11, mostró cómo crear una cuenta de servicio de datos WCF JSONP con un atributo JSONPSupportBehavior disponible para download desde la galería de códigos MSDN (y se supone que forma parte del espacio de nombres Microsoft.Data.Services.Extensions). En esta publicación, mostraré un ejemplo simple que utiliza el atributo y jQuery para realizar una llamada de dominio cruzado JSONP para un servicio de datos WCF.

Configuración del entorno del

Primero empecé mediante la creación de dos aplicaciones ASP.NET Web diferente. La primera aplicación incluye la página de llamadas y la segunda incluye el servicio de datos WCF. Luego, creé en la segunda aplicación web un modelo de Entity Framework y el WCF Data Service de ese modelo. También agregué la clase JSONPSupportBehavior.cs que existe en el link que proporcioné anteriormente. La clase incluye la implementación de JSONPSupportBehavior que implementa la interfaz WCF IDispatchMessageInspector. También incluye el JSONPSupportBehaviorAttribute que uso en mi código. El código es simple y se ve así:

[JSONPSupportBehavior] 
public class SchoolDataService : DataService<SchoolEntities> 
{ 
    // This method is called only once to initialize service-wide policies. 
    public static void InitializeService(DataServiceConfiguration config) 
    {  
    config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);  
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; 
    } 
} 

Hacer la llamada JSONP

En la segunda aplicación web que he creado un formulario web que llevará a cabo el ejemplo de llamada JSONP. Aquí está el código que realiza la llamada:

<!DOCTYPE html> 
<html> 
<head runat="server"> 
    <title>JSONP Call</title> 
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.js" type="text/javascript"></script> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <output id="result"> 
    </output> 
    </form> 
    <script type="text/javascript"> 
     $.getJSON('http://localhost:23330/SchoolDataService.svc/Courses?$format=json&$callback=?', 
     function (response) { 
      $.each(response.d, function (index, value) { 
       var div = document.createElement('div'); 
       div.innerHTML = value.Title; 
       $('#result').append(div); 
      }) 
     });   
    </script> 
</body> 
</html> 

Vamos a explorar el código de formulario web: Al principio utilizo Microsoft CDN con el fin de recuperar la biblioteca de jQuery. Luego, he creado un elemento de salida HTML5 para agregarle la salida de la llamada. En el script principal utilizo la función getJSON de jQuery que llama al Servicio de datos WCF. Preste atención que para obtener una respuesta JSON del Servicio de datos WCF necesita usar el parámetro de cadena de consulta $ format = json. Después de recuperar los datos, repito y creo un elemento div para cada título del curso que se recuperó. Esto se hace en la función de éxito que conecté en la llamada a la función getJSON. Aquí está la salida de ejecutar el código:

enter image description here

Resumen

En el post que suministró un ejemplo sencillo de hacer una llamada JSONP a un servicio de datos WCF utilizando jQuery. Este tipo de solución puede ayudarle a consumir los servicios de datos WCF que existen en otros dominios desde su lado del cliente. En una publicación de seguimiento, mostraré el mismo ejemplo usando la nueva biblioteca datajs

Cuestiones relacionadas