C# 如何在Web API和OData中进行修补
从阅读中可以清楚地看出,C# 如何在Web API和OData中进行修补,c#,.net,asp.net-web-api,odata,http-patch,C#,.net,Asp.net Web Api,Odata,Http Patch,从阅读中可以清楚地看出,补丁谓词不应获取部分更新实体的值,而应获取以下操作: …但是,对于面片,封闭的实体包含一组 描述资源当前如何驻留在 应修改源服务器以生成新版本 在MSDN中,对于Delta类,也很清楚,如描述所示: 使用此增量跟踪的更改覆盖原始图元 与以下描述不同: 使用存储在此增量中的值覆盖原始实体 到目前为止还不错,但我找不到用OData发送这些“指令”的方法,不管我做什么,Delta.Patch只替换这些值 补丁请求的语法应该是什么 我尝试的方法是: PATCH http://lo
补丁
谓词不应获取部分更新实体的值,而应获取以下操作:
…但是,对于面片,封闭的实体包含一组
描述资源当前如何驻留在
应修改源服务器以生成新版本
在MSDN中,对于Delta类,也很清楚,如描述所示:
使用此增量跟踪的更改覆盖原始图元
与以下描述不同:
使用存储在此增量中的值覆盖原始实体
到目前为止还不错,但我找不到用OData发送这些“指令”的方法,不管我做什么,Delta.Patch只替换这些值
补丁请求的语法应该是什么
我尝试的方法是:
PATCH http://localhost:55783/Products(1) HTTP/1.1
User-Agent: Fiddler
Host: localhost:55783
Content-Length: 19
Content-type: application/json
{ "Price": 432 }
及
这附近的东西
更新: 多亏了Michael Moore,通过阅读ILSpy的整个Delta类,我认为这确实是补丁动词设计中的一个bug。
我不确定您想要实现的目标是否可能。至少不使用
Delta.Patch(..)
假设您拥有产品
实体以及补丁
操作中的某个地方
[AcceptVerbs("PATCH")]
public void Patch(int productId, Delta<Product> product)
{
var productFromDb = // get product from db by productId
product.Patch(productFromDb);
// some other stuff
}
Initialize
方法如下所示
private void Initialize(Type entityType)
{
// some argument validation, emitted for the sake of brevity
this._entity = (Activator.CreateInstance(entityType) as TEntityType);
this._changedProperties = new HashSet<string>();
this._entityType = entityType;
this._propertiesThatExist = this.InitializePropertiesThatExist();
}
正如您所见,它获取已更改的属性,对它们进行迭代,并将传递给Patch action的实例的值设置为从db获取的实例的值。因此,您要传递的操作、要添加的属性名称和值不会反映任何内容
propertyAccessor.Copy(此.\u实体,原件)
方法的主体
public void Copy(TEntityType from, TEntityType to)
{
if (from == null)
{
throw Error.ArgumentNull("from");
}
if (to == null)
{
throw Error.ArgumentNull("to");
}
this.SetValue(to, this.GetValue(from));
}
谢谢你的回答!我觉得在这里使用反射器会有帮助。。。这是一个bug吗?因为规范和MSDN都在谈论“说明”而不是值。那么Delta.Put和Delta.Patch有什么区别呢?顺便问一下,你是在微软工作还是“只”一个热心的程序员?@gdoron你是在谈论MSDN for Delta的补丁方法吗?@gdoron你可能会感到惊讶,但Delta的PUT方法没有那么大的不同,唯一的区别是在PUT方法中,它也会遍历未更改的属性列表,并只复制那些值。不,我不在微软工作:)顺便说一句,我用了IlSpy而不是反射器:)@gdoron,正如你在文章中提到的,它只是说它用Delta跟踪的更改覆盖了原始实体。你们看到了Delta如何跟踪变化,它不寻找指令,在MSDN中我找不到任何关于指令的单词。我同意你的看法,RFC规范谈到指令。那么你是说Delta.Put不会部分更新实体,而是完全覆盖实体,就像简单的Http Put方法一样?!
private void Initialize(Type entityType)
{
// some argument validation, emitted for the sake of brevity
this._entity = (Activator.CreateInstance(entityType) as TEntityType);
this._changedProperties = new HashSet<string>();
this._entityType = entityType;
this._propertiesThatExist = this.InitializePropertiesThatExist();
}
// some argument checks
PropertyAccessor<TEntityType>[] array = (
from s in this.GetChangedPropertyNames()
select this._propertiesThatExist[s]).ToArray<PropertyAccessor<TEntityType>>();
PropertyAccessor<TEntityType>[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
PropertyAccessor<TEntityType> propertyAccessor = array2[i];
propertyAccessor.Copy(this._entity, original);
}
public void Copy(TEntityType from, TEntityType to)
{
if (from == null)
{
throw Error.ArgumentNull("from");
}
if (to == null)
{
throw Error.ArgumentNull("to");
}
this.SetValue(to, this.GetValue(from));
}