多POST方法的OData的Web API。 应该/可以发生?(Multiple POST me

2019-10-20 04:11发布

这个问题也许是一个思想体系一个...

我有一个要求,从应用程序中调用通过服务代理的OData的网络API创建多个记录。

目前,我被(通过服务代理)调用POST方法多次,然后调用保存更改批量请求这样做。 例如。

    container.AddToColours(new Colour { Id = 1, Name = "Green" });
    container.AddToColours(new Colour { Id = 2, Name = "Orange" });
    container.SaveChanges(SaveChangesOptions.Batch);

这种方法的缺点是,在我的Web API控制器POST方法被调用了两次,因此产生两个INSERT语句。

现在,如果我的客户这样做

    container.AddToColours(new List<Colour>() { new Colour { Id = 1, Name = "Green" }, new Colour { Id = 2, Name = "Orange" }});
    container.SaveChanges(SaveChangesOptions.Batch);

那么只有一个插入语句将创建一个同时插入两个记录。

该问题是;

这可能吗? (我可能最终有两个POST方法 - 一个为单一颜色相互接受的颜色列表)。

这是可能通过服务代理?

这是否触犯每/中的OData / REST本书的任何规则?

这是道德的?

这是调皮?

编辑

已经重新此,我已经能够如下建议创建一个自定义批量处理程序。 我希望这可以帮助别人。 它保存在一个批次中的一个事务中进行,所以如果该批次的一部分失败,那么所有部件失效的所有更改。 但是,重要的是,尝试以保存该批次的所有操作,无论先前的成功或失败,这样的错误信息可以为操作返回。

我在这里使用的样本为基础:

http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v3/ODataEFBatchSample/

但做了以下修改:

改变EntityFrameworkBatchHandler.ExecuteChangeSet方法:

    private async Task ExecuteChangeSet(ChangeSetRequestItem changeSet, IList<ODataBatchResponseItem> responses, CancellationToken cancellation)
    {
        using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadUncommitted }, TransactionScopeAsyncFlowOption.Enabled))
        {
            responses.Add((ChangeSetResponseItem) await new ChangeSetBatchRequestItem(changeSet).SendRequestAsync(Invoker, cancellation));

            if (responses.All(x => (x as ChangeSetResponseItem).Responses.All(y => y.IsSuccessStatusCode)))
            { 
                scope.Complete();
            }
        }
    }

我认为,这意味着它不依赖于EF的。 我除去HttpRequestMessageExtensions.cs并创建了一个新的类,ChangeSetBatchRequestItem这是除了以下方法完全一样System.Web.OData.Batch.ChangeSetRequestItem:

    public override async Task<ODataBatchResponseItem> SendRequestAsync(HttpMessageInvoker invoker, CancellationToken cancellationToken)
    {
        if (invoker == null)
        {
            throw new ArgumentNullException("invoker");
        }

        Dictionary<string, string> contentIdToLocationMapping = new Dictionary<string, string>();
        List<HttpResponseMessage> responses = new List<HttpResponseMessage>();

        try
        {
            foreach (HttpRequestMessage request in Requests)
            {
                responses.Add(await SendMessageAsync(invoker, request, cancellationToken, contentIdToLocationMapping));
            }
        }
        catch
        {
            DisposeResponses(responses);
            throw;
        }

        return new ChangeSetResponseItem(responses);
    }

这就是很多。

Answer 1:

感谢您的回答,在这里,我的回答你的问题。

  1. 在请求主体POST多于一个实体(如果它不是一个批处理请求)不是一个常规的OData请求。
  2. 在控制器被调用两次Post方法并不意味着客户端发送两个POST请求。 实际上,客户端发出批量要求,其中包含了2 POST作为其子多个请求。 而批量处理调度各子请求发送到Web API管线,然后组成的WebAPI所有子回应到一个发送回请求者。 欲了解更多请参考https://aspnetwebstack.codeplex.com/wikipage?title=Web%20API%20Request%20Batching


文章来源: Multiple POST methods OData Web API. Should/can it happen?