本文介绍了多POST方法的OData的Web API。应该/可以发生?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题可能是一个思想体系1 ...

This question is perhaps an idealogical one...

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

I have a requirement to create multiple records from an application calling an OData Web API through a service proxy.

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

At the moment, I'm doing this by invoking the post method multiple times (through a service proxy) and then calling save changes to batch the requests. Eg.

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

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

The downside of this is that in my web api controller the post method is called twice and so generates two insert statements.

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

Now, if in my client did this

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

那么只有一个插入语句将被创建,一次插入两个记录。

Then only a single insert statement would be created that inserts both records at once.

的问题是;

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

Is this possible? (I'd probably end up having two POST methods - one for a single colour another to accept a list of colours).

这可能是通过服务代理?

Is this possible through a service proxy?

这是否折断一切的/任何规则中的OData / REST的书吗?

Does this break every/any rule in the OData/REST book?

这是道德的?

这是调皮?

修改

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

Having revisited this I've been able to create a custom batch handler as suggested below. I'm hoping that this helps others. It saves all changes made in a batch in a single transaction so if one part of the batch fails then all parts fail. But, importantly, attempts are made to save for all operations in the batch regardless of previous successes or failures so error messages can be returned for operation.

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

I used the sample here as a basis:

但做了以下修改:

改EntityFrameworkBatchHandler.ExecuteChangeSet方法:

Changed EntityFrameworkBatchHandler.ExecuteChangeSet method to:

    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的。我删除了Htt prequestMessageExtensions.cs并创建一个新的类,ChangeSetBatchRequestItem这是完全一样System.Web.OData.Batch.ChangeSetRequestItem除了下面的方法:

I believe that this means that it is not tied to EF at all. I removed HttpRequestMessageExtensions.cs and created a new class, ChangeSetBatchRequestItem which is exactly the same as System.Web.OData.Batch.ChangeSetRequestItem except for the following method:

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

这就是今天的很多东西。

And that's the lot.

推荐答案

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

Thanks for the answer, and here my answer to you question.


  1. 在一个请求体POST多个实体(如果它不是一个批处理请求)不是一个常规的OData请求。

  2. 在控制器被调用两次Post方法并不意味着客户端发送两个POST请求。其实,客户发出了一批请求,其中包含了2 POST作为其子多个请求。和分批处理调度每个子请求发送到网页API管道,然后的WebAPI组成全部副反应成一个,并将其发送回请求方。欲了解更多请参考的

这篇关于多POST方法的OData的Web API。应该/可以发生?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 14:28