從 Web Api 2 中的 OData 客戶端呼叫更新檔的正確方法是什麼
在 web api 團隊創建的 OData 範例之後,我的控制器具有以下支持更新檔:
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 和描述。另外,如果我調試服務方法並呼叫
GetChangedPropertyNames在 item 上,返回其所有屬性名稱。我應該在客戶端上創建某種 Delta 實例嗎?
我了解服務的斷開連接性質,因此服務端沒有用於跟踪更改的上下文,但在我看來,api 團隊添加了對更新檔的支持是有原因的,所以我想知道客戶端是否應該以不同的方式呼叫更新。
更新
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
Microsoft.OData.Client 版本 6.2.0 現在支持客戶端屬性跟踪。它將僅檢測實體的修改屬性並將更新請求作為 PATCH 而不是 PUT 發送以滿足您的場景要求。有關詳細資訊,請參閱此部落格文章: https ://devblogs.microsoft.com/odata/tutorial-sample-client-property-tracking-for-patch/