[英]Optimistic Concurrency Handling - Asp.Net WebApi Odata V4
这是我的OdataController
的Patch
方法
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> patch)
{
Validate(patch.GetInstance());
Product product = await service.Products.GetAsync(key);
if (product == null)
return NotFound();
patch.Put(product);
try
{
await service.Products.UpdateAsync(product);
}
catch (DbUpdateConcurrencyException)
{
if (!await service.Products.ExistAsync(key))
return NotFound();
else
throw;
}
return Updated(product);
}
我的模型有一个属性:
[Timestamp]
public byte[] RowVersion { get; set; }
DbUpdateConcurrencyException
似乎根本不起作用。 我需要使用Etag实现并发检查机制。 我在这里看到了一些示例。但是他们没有在其中使用Delta方法。
就像是:
[CustomConcurrencyCheck]
public async Task<IHttpActionResult> Put([FromODataUri] int key, Delta<Product> patch)
{
...
}
提供一个简单的例子将受到高度赞赏。
首先,在WebApiConfig
在创建模型时,必须指定哪种属性是ETag,在这种情况下:
var builder = new ODataConventionModelBuilder();
builder.EntityType<Product>()
.Property(p => p.RowVersion)
.IsConcurrencyToken();
稍后,您可以从控制器中Patch
方法的ODataQueryOptions<T>
参数检索ETag:
[AcceptVerbs("PATCH", "MERGE")]
public IHttpActionResult Patch([FromODataUri] int key, Delta<Product> delta, ODataQueryOptions<Product> options) {
var existingEntity = //Code to get existing entity by ID, 404 if not found
byte[] requestETag = options.IfMatch["RowVersion"] as byte[];
if(!requestETag.SequanceEqual(existingEntity.RowVersion)) { //Simplified if-statement, also do null-checks and such
// ETags don't match, return HTTP 412
return StatusCode(HttpStatusCode.PreconditionFailed);
} else {
// The ETags match, implement code here to update your entity
// You can use the 'Delta<Product> delta' parameter to get the changes and use the 'Validate' function here
// ...
这是我使用的解决方案,它是一项简单的检查,以查看请求更新的客户端是否具有该服务具有的对象的相同版本。 我的解决方案的一个显着缺点是,我必须从数据库中检索现有对象才能使其正常工作,这会降低性能。
这是If-Match
头的代码, ODataQueryOptions<T>
也具有.IfNoneMatch[VersionColumnName]
可用。 您可以在Get
方法中使用它。 如果If-None-Match
标头等于您的RowVersion
,则可以返回HTTP 304 (Not modified)
并节省一些带宽。
如果您要实现自己的自定义属性,这是一个非常简单的示例。 至少,我会将其中一些逻辑移到辅助类中,以便可以重用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.