rest - tutorial - web api methods
¿Cuál es la forma actualmente recomendada de realizar actualizaciones parciales con Web API? (1)
Me pregunto cómo implementar actualizaciones parciales con la interfaz RESTful de ASP.NET Web API. Digamos, por ejemplo, que estamos pasando objetos por el cable de la siguiente estructura:
public class Person {
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
¿Cómo se puede actualizar solo partes de una Person
a la vez, por ejemplo, la propiedad Email
? ¿Se recomienda implementar esto a través de OData y el verbo PATCH, o sería mejor implementar PATCH uno mismo?
No hay soporte en la última versión estable actual de la API web (desde agosto de 2012). Por lo tanto, si todo lo que desea utilizar es Web API RTM, tendrá que implementar toda la instalación de tuberías usted mismo.
Dicho esto, el paquete de presentación preliminar de OData admite actualizaciones parciales muy bien a través del nuevo objeto Delta<T>
. Actualmente el paquete Microsoft.AspNet.WebApi.OData ya está en la versión RC (0.3) y se puede obtener desde aquí: http://www.nuget.org/packages/Microsoft.AspNet.WebApi.OData
Una vez que lo instales, puedes usar eso en consecuencia:
[AcceptVerbs("PATCH")]
public void Patch(int id, Delta<Person> person)
{
var personFromDb = _personRepository.Get(id);
person.Patch(personFromDb);
_personRepository.Save();
}
Y lo llamarías así del cliente:
$.ajax({
url: ''api/person/1'',
type: ''PATCH'',
data: JSON.stringify(obj),
dataType: ''json'',
contentType: ''application/json'',
success: function(callback) {
//handle errors, do stuff yada yada yada
}
});
La ventaja obvia de esto es que funciona para cualquier propiedad, y no tiene que importar si actualiza el Email
o el nombre de Username
o lo que sea.
También es posible que desee examinar esta publicación, ya que muestra una técnica muy similar http://techbrij.com/http-patch-request-asp-net-webapi
EDITAR (más información): Para usar simplemente PATCH , no necesita habilitar nada relacionado con OData, excepto para agregar el paquete OData, para obtener acceso al objeto Delta<TEntityType>
.
Entonces puedes hacer esto:
public class ValuesController : ApiController
{
private static List<Item> items = new List<Item> {new Item {Id = 1, Age = 1, Name = "Abc"}, new Item {Id = 2, Age = 10, Name = "Def"}, new Item {Id = 3, Age = 100, Name = "Ghj"}};
public Item Get(int id)
{
return items.Find(i => i.Id == id);
}
[AcceptVerbs("PATCH")]
public void Patch(int id, Delta<Item> item)
{
var itemDb = items.Find(i => i.Id == id);
item.Patch(itemDb);
}
}
Si tu artículo es, digamos:
{
"Id": 3,
"Name": "hello",
"Age": 100
}
Puede PATCH a /api/values/3
con:
{
"Name": "changed!"
}
y eso actualizará correctamente su objeto.
Delta<TEntity>
hará un seguimiento de los cambios por usted. Es una clase dinámica que actúa como un proxy liviano para su Tipo y comprenderá las diferencias entre el objeto original (es decir, desde el DB) y el que pasa el cliente.
Esto NO afectará el resto de su API de ninguna manera (excepto, por supuesto, reemplazar las DLL con las más nuevas para facilitar las dependencias del paquete OData).
He agregado un proyecto de muestra para demostrar el trabajo de PATCH + Delta: puede obtenerlo aquí (es VS2012) https://www.dropbox.com/s/hq7wt3a2w84egbh/MvcApplication3.zip