2012-09-26 20 views
7

Estoy tratando de implementar lo que pensé que era un escenario simple utilizando un servicio OData proporcionado por los servicios de datos WCF (utilizando la aplicación OData V3/json; odata = formato de carga prolija, por ahora. Puedo usar el formato JSON Light en futuro). El escenario básico dice así:¿Cómo actualizo una entidad OData y modifico sus propiedades de navegación en una sola solicitud?

Tengo dos entidades:

class Person 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public virtual PersonCategory Category { get; set; } 
} 

class PersonCategory 
{ 
    public int ID { get; set; } 
    public string Description { get; set; } 
    public virtual ICollection<Person> People { get; set; } 
} 

Ahora, quiero crear una simple página de edición para una persona. Esta página de edición puede tener una entrada para el Nombre y una entrada o menú desplegable para la Categoría de la Persona.

Por lo tanto, el escenario va:

  1. Código descargas de la persona que utiliza $ ampliar para la Categoría: GET /api.svc/People(1)?$expand=Category
  2. usuario edita tanto en la persona de Nombre de la propiedad y su categoría.
  3. El código de la página realiza una única solicitud para actualizar las propiedades de nombre y categoría de esa persona.

La clave aquí está en "una sola solicitud". Esta es la parte que me cuesta encontrar documentación. He visto ejemplos en los que dividieron el número 3 anterior en dos solicitudes. Algo como esto (no recuerdo el formato exacto - Tampoco estoy seguro de si habría que eliminar el enlace antes de hacer la Categoría PUT):

PATCH /api.svc/People(1) with content: {"Name": "new name" } 
PUT /api.svc/People(1)/$links/Category with content: { "url": "/api.svc/Categories(2)" } 

Pero, también he oído dicho, pero no demostrado, que es posible implementar esta actualización como una única solicitud con el cambio a la propiedad de navegación Categoría especificada en línea con los otros cambios a la entidad Persona. ¿Podría alguien darme un ejemplo de cómo se podría hacer esto? Además, ¿puede mostrarme cómo se haría con una propiedad de navegación de muchos a muchos, en lugar de la opción de uno a muchos que he descrito anteriormente?

Y, por último, actualmente estoy usando el formato JSON detallado, V3. ¿Sus respuestas a las preguntas anteriores serían diferentes si en su lugar utilicé el nuevo formato de luz JSON? ¿Si es así, cómo?

+0

Puede enviar una solicitud por lotes: sería una solicitud única que contiene ambas operaciones. – Pawel

+0

¿No hay otra manera de hacer esto que no sea una solicitud por lotes? Eso agregaría una complejidad adicional al código de disparo circular del lado del cliente que preferiría evitar. Idealmente, me gustaría simplemente formatear mi solicitud de PATCH/api/Activity (1) para que sea algo como: {"category": {"__deferred": {"uri": "/api.svc/Categories(2)"} }} Esto no parece funcionar sin embargo. Recibo una respuesta 204, pero la propiedad permanece sin cambios en el lado del servidor. –

+0

Las denominadas actualizaciones profundas (que es lo que quiere aquí) no son compatibles con WCF Data Services. De hecho, incluso OData en sí mismo no lo define realmente. Puede ser bastante complicado en cuanto a lo que significa en algunos casos. Me temo que el lote es la única solución para esto. Inserciones profundas son compatibles (pero de nuevo solo insertos, sin modificar nada existente). –

Respuesta

4

comentario de Pratik era la respuesta (Pratik si desea volver a publicar esto como una respuesta, voy a marcarlo como tal - gracias!):

Pregunta: ¿Quieres actualizar la categoría instancia o desea actualizar algunas de las propiedades de la instancia de categoría. No hay forma de hacer lo posterior más allá del lote. Para el primero, puede hacer algo como: {"Nombre": "nuevo nombre", "Categoría": {"__metadata": {"uri": "/api.svc/Categories(2)"}}}. Espero que esto ayude. - Pratik

+0

Hmm esto no funciona para mí con actualizaciones de todos modos – rethenhouser2

+0

Hmm funciona cuando uso el url \ uri completo para los metadatos del enlace, entonces está bien. – rethenhouser2

4

he encontrado dos formas de representar las propiedades de navegación en línea:

application/json;odata=verbose - { "Name": "new name", "Category": { "__metadata": { "uri": "Categories(2)" }}}

application/json - { "Name": "new name", "[email protected]": "Categories(2)" }

+0

Su primer ejemplo es la especificación OData 3.0. Tu segundo es OData 4.0 – JDB

0

No es necesario un lote, nunca más. Puedes hacerlo en una llamada. Simplemente necesita enviar también las propiedades modificadas y dejar que el repositorio maneje las propiedades modificadas.

public class Person 
{ 
    public string FirstName {get;set;} 
    public string LastName {get;set;} 
    public int Age {get;set;} 
} 

Digamos que usted notará el primer nombre tiene un error tipográfico, Jhon y que se supone que es Juan. Puede editar el primer nombre y enviarlo. Entonces tienes el siguiente modelo de objeto. Se puede conseguir esto en 1 de dos maneras:

  • tienen dos parámetros y establecer BodyStyle = WebMessageBodyStyle.Wrapped
  • Basta con crear un modelo de objeto genérico con dos propiedades: Propiedad es de tipo T y la propiedad 2 es una lista.

Así que le envíe este JSON:

[{ FirstName = 'John' }, ['FirstName']] 

Ahora en el lado del servidor, puede hacer lo que tiene que hacer.

Si no desea enviar las propiedades modificadas, puede adivinar las propiedades modificadas al elegir cualquier propiedad cuyo valor no sea la propiedad predeterminada.

{Nombre = 'John'}

continuación, puede utilizar algunos métodos para ver qué propiedades han cambiado:

Cuestiones relacionadas