Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Web API和OData中进行修补_C#_.net_Asp.net Web Api_Odata_Http Patch - Fatal编程技术网

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));
}