为什么我的OData 4 Batch无法提取上一个请求的请求主体

时间:2019-03-12 14:52:55

标签: asp.net-core odata postman asp.net-core-2.1

我正在使用Microsoft.AspNetCore.OData NuGet v7.1.0开发ASP.NET Core 2.2 API,并且正在尝试使用Postman v7.0.5测试OData批处理。

我遇到的问题是,它总是看不到我批次中最后一个POST请求中的数据。在响应中,除最后一条消息外,我对每个帖子都获得“ 201 Created”(创建201),它返回“ 400 Bad Request”,因为它没有在最后一个请求正文中获取数据。

这是我的Startup.cs的相关部分,其中启用了OData批处理;

app.UseODataBatching();
app.UseMvc(routeBuilder =>
{
    routeBuilder
        .MapODataServiceRoute("ODataRoutes", "api/v1",
             modelBuilder.GetEdmModel(app.ApplicationServices), 
             new DefaultODataBatchHandler());
});

在邮递员中,我有一个POST请求

{{url}}/api/v1/$batch

在“请求->标头”部分,我将Content-Type标头设置为

multipart/mixed; boundary=batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0

请求的正文设置为“原始”和“文本”

下面是请求正文;

--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /api/v1/AddressComplianceCode HTTP/1.1
OData-Version: 4.0
Content-Type: application/json
Accept: application/json;odata.metadata=minimal

{
  "Code": "Z1",
  "Description": "Test Batch Z1",
  "Active": true
}

--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /api/v1/AddressComplianceCode HTTP/1.1
OData-Version: 4.0
Content-Type: application/json
Accept: application/json;odata.metadata=minimal

{
  "Code": "Z2",
  "Description": "Test Batch Z2",
  "Active": true
}

--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /api/v1/AddressComplianceCode HTTP/1.1
OData-Version: 4.0
Content-Type: application/json
Accept: application/json;odata.metadata=minimal

{
  "Code": "Z3",
  "Description": "Test Batch Z3",
  "Active": true
}

--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /api/v1/AddressComplianceCode HTTP/1.1
OData-Version: 4.0
Content-Type: application/json
Accept: application/json;odata.metadata=minimal

{
  "Code": "Z4",
  "Description": "Test Batch Z4",
  "Active": true
}

--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0--

这是回应;

--batchresponse_f2c84aaf-dc39-4f20-8da0-881f402436fa
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 201 Created
Location: https://localhost:44331/api/v1/AddressComplianceCode('Z1')
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
OData-Version: 4.0

{"@odata.context":"https://localhost:44331/api/v1/$metadata#AddressComplianceCode/$entity","Code":"Z1","Description":"Test Batch Z1","MarkedForRetirement":false,"RetirementDate":null,"LastModifiedDate":"2019-03-12T10:19:20.9434728-04:00","LastModifiedBy":null,"CreatedDate":"2019-03-12T10:19:20.9434728-04:00","CreatedBy":null,"Delete":false,"Active":true}
--batchresponse_f2c84aaf-dc39-4f20-8da0-881f402436fa
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 201 Created
Location: https://localhost:44331/api/v1/AddressComplianceCode('Z2')
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
OData-Version: 4.0

{"@odata.context":"https://localhost:44331/api/v1/$metadata#AddressComplianceCode/$entity","Code":"Z2","Description":"Test Batch Z2","MarkedForRetirement":false,"RetirementDate":null,"LastModifiedDate":"2019-03-12T10:19:21.2241031-04:00","LastModifiedBy":null,"CreatedDate":"2019-03-12T10:19:21.2241031-04:00","CreatedBy":null,"Delete":false,"Active":true}
--batchresponse_f2c84aaf-dc39-4f20-8da0-881f402436fa
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 201 Created
Location: https://localhost:44331/api/v1/AddressComplianceCode('Z3')
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
OData-Version: 4.0

{"@odata.context":"https://localhost:44331/api/v1/$metadata#AddressComplianceCode/$entity","Code":"Z3","Description":"Test Batch Z3","MarkedForRetirement":false,"RetirementDate":null,"LastModifiedDate":"2019-03-12T10:19:21.5068813-04:00","LastModifiedBy":null,"CreatedDate":"2019-03-12T10:19:21.5068813-04:00","CreatedBy":null,"Delete":false,"Active":true}
--batchresponse_f2c84aaf-dc39-4f20-8da0-881f402436fa
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 400 Bad Request
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
OData-Version: 4.0

{"error":{"code":"","message":"The input was not valid.","details":[{"code":"","message":"The input was not valid."}]}}
--batchresponse_f2c84aaf-dc39-4f20-8da0-881f402436fa--

无论我在请求中添加了多少POST节(我已经测试过2、3和4),最后一个请求始终都无法传递请求正文值。

我已经查看了www.odata.org网站上的Batch高级教程,以及我可以找到的所有相关SO帖子。我还使用过滤器尝试了Github issues pages

is:issue is:open batch 

到目前为止一切都没有运气。

我在这里想念什么?

1 个答案:

答案 0 :(得分:1)

根据我自己的经验,我想这是因为您是通过邮递员发送LF,而不是CRLF。

Postman会发送您输入的任何换行符(可能是从喜欢LF的东西粘贴进来的),但是多部分/混合数据需要CRLF。仅发送LF会使ODataMultipartMixedBatchReader混淆边界线是否为终点边界,并导致将终点边界标记添加到请求中。反过来,这会混淆ASP.NET Core方面的模型绑定程序,从而无法反序列化请求正文。