Как правильно вызвать патч из клиента 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

Другие вопросы по тегам