Как правильно вызвать патч из клиента OData в Web Api 2?
Следуя образцам OData, созданным командой web api, у моего контроллера есть следующее для поддержки Patch:
public HttpResponseMessage Patch([FromODataUri] int key, Delta<Foo> item)
{
var dbVersion = myDb.GetById(key);
if(dbVersion == null)
throw Request.EntityNotFound();
item.Patch(dbVersion);
myDb.Update(dbVersion);
return Request.CreateResponse(HttpStatusCode.NoContent);
}
и используя автоматически сгенерированный клиент (полученный из DataServiceContext
), Я отправляю запрос на исправление следующим образом:
var foo = svcContainer.Foos.Where (f => f.Id == 1).SingleOrDefault();
foo.Description = "Updated Description";
svcContainer.UpdateObject(foo);
svcContainer.SaveChanges(SaveChangesOptions.PatchOnUpdate);
Однако, отслеживая вызов в fiddler, я вижу, что все остальные свойства Foo сериализуются и отправляются в сервис. Это правильное поведение? Я ожидал, что только Id и Description будут отправлены по проводам. Кроме того, если я отлаживаю сервисный метод и вызываю
GetChangedPropertyNames
для элемента возвращаются все имена его свойств.
Должен ли я создавать какой-то экземпляр Delta на клиенте?
Я понимаю отключенную природу сервиса и, следовательно, у сервисной стороны нет контекста для отслеживания изменений, но мне кажется, что команда api по какой-то причине добавила поддержку patch, поэтому я хотел бы знать, должен ли клиент вызывать обновление другим способом.
Обновить
Предоставленная YiDing ссылка объясняет, как создать настоящий запрос PATCH от клиента (используя Microsoft.OData.Client.DataServiceContext
созданный Microsoft.OData.Client 6.2.0
и выше. Для удобства вот фрагмент кода:
var svcContainer = new Default.Container(<svcUri>);
var changeTracker = new DataServiceCollection<Foo>(svcContainer.Foos.Where(f => f.Id == 1));
changeTracker[0].Description = "Patched Description";
svcContainer.SaveChanges();
DataServiceCollection
реализует отслеживание свойств, и, используя этот шаблон, только обновленные свойства отправляются в службу. Без использования DataServiceCollection
и просто используя
svcContainer.UpdateObject(foo);
svcContainer.SaveChanges();
все свойства по-прежнему передаются по проводам, несмотря на документацию об обратном, по крайней мере на Microsoft.OData.Client 6.7.0
1 ответ
Отслеживание свойств на стороне клиента теперь поддерживается в Microsoft.OData.Client версии 6.2.0. Он обнаружит только измененные свойства объекта и отправит запрос на обновление как PATCH вместо PUT, чтобы удовлетворить требования вашего сценария. Пожалуйста, обратитесь к этому сообщению в блоге для получения более подробной информации: http://blogs.msdn.com/b/odatateam/archive/2014/04/10/client-property-tracking-for-patch.aspx