C#Odata WebApi与byte []的并发

时间:2015-12-16 11:17:08

标签: c# asp.net-web-api odata

我为OData V4设置了一个WebApi端点。我没有直接使用实体框架,而是定义了一些POCO。

public class ServiceDTO
{
    public string Id { get; set; }
    public string Name { get; set; }
    [Timestamp]
    public byte[] RowVersion { get; set; }
}

我的问题是在Odata控制器的Patch方法中我将检查If-Match标题如:

    [AcceptVerbs("PATCH", "MERGE")]
    public async Task<IHttpActionResult> Patch([FromODataUri] string key, Delta<ServiceDTO> patch, ODataQueryOptions<ServiceDTO> options)
    {
        if (patch == null)
        {
            var responseMessage = new HttpResponseMessage();
            responseMessage.StatusCode = HttpStatusCode.ExpectationFailed;
            responseMessage.Content = new StringContent("Missing properties");
            return ResponseMessage(responseMessage);
        }

        Validate(patch.GetEntity());

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (options.IfMatch != null)
        {
            var result = this.repository.Get(options).AsQueryable().Where(u => u.Id == key);
            if (!result.Any())
            {
                // The entity doesn't exist on the database and as the request contains an If-Match header we don't
                // insert the entity instead (No UPSERT behavior if the If-Match header is present).
                return NotFound();
            }
            else if (!((IQueryable<ServiceDTO>)options.IfMatch.ApplyTo(result)).Any())
            {
                // The ETag of the entity doesn't match the value sent on the If-Match header, so the entity has
                // been modified by a third party between the entity retrieval and update..
                return StatusCode(HttpStatusCode.PreconditionFailed);
            }
            else
            {
                // The entity exists in the database and the ETag of the entity matches the value on the If-Match 
                // header, so we update the entity.
                var service = await this.repository.Get(key);
                patch.Patch(service);
                await this.repository.Update(service);
                if (service == null)
                    return BadRequest();
                return Ok(service);
            }
        }
        else
        {
            var responseMessage = new HttpResponseMessage();
            responseMessage.StatusCode = (HttpStatusCode)428;
            return ResponseMessage(responseMessage);
        }
    }

在POCO中使用byte []我将始终以Precondition失败告终。当我将数据类型从byte []替换为string或int64时,一切正常。

我也尝试将DataAnnotation从[Timestamp]替换为[ConcurrencyCheck],但这没有效果。

我们之前在另一个带有byte的项目中使用过此代码,但我们直接使用EF。

存储库在运行时解析,它可以是与EF一起使用的存储库,也可以是与另一个后端一起使用的另一个自定义存储库。

我使用EF存储库和内存存储库进行了测试。

0 个答案:

没有答案