My Products
Help
omelhus
PARTNER

Exception when using $batch. "Error parsing HTTP message header byte 5 of message System.Byte[]."

by omelhus

Request

POST /API/controller/api/v1/$batch HTTP/1.1
Accept: application/json
Authorization: Bearer ...
Content-Length: 345
Content-Type: multipart/mixed; boundary=a49c65ed-9964-4c48-92b0-99754c008590
Host: integration.visma.net
User-Agent: HTTPie

--a49c65ed-9964-4c48-92b0-99754c008590
Content-Type: application/http; msgtype=request
GET /api/v1/salesordertype/SO HTTP/1.1
Host: integration.visma.net

--a49c65ed-9964-4c48-92b0-99754c008590
Content-Type: application/http; msgtype=request
GET /api/v1/organization HTTP/1.1
Host: integration.visma.net

--a49c65ed-9964-4c48-92b0-99754c008590--

 

Response

HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache,no-cache
Connection: close
Content-Type: application/json; charset=utf-8
Date: Mon, 16 Oct 2023 08:29:41 GMT
Expires: -1
Feature-Policy: geolocation 'none'; vr 'none'; payment 'none'; midi 'none'; microphone 'none'; fullscreen 'none'; encrypted-media 'none'; camera 'none'; autoplay 'none';
Ipp-Request-Id: 3cd9b6e5-b720-43cd-8983-069b9d98cb13
Pragma: no-cache
Referrer-Policy: origin-when-cross-origin
Server: Nginx
Set-Cookie: .ASPXROLES=YyiGvqobVOCIWgmoyV1Rww_q782ug9EidG_2W9yAmhCNWSirt3d5uUnxz27HFCpk_QRQz3w_0YQSqn82SVdFSgqqzwMQu7Xw0-SHaJrWMagz8qzVI9j-yn2Ffnzww2H-OMFzdnA_0Jb9c8Ihz_F1vQxfboL7K5IbQGl7G5XwtA9K_QDbrqD3bvIxcsUs2EQjKMUAdPoGw81ueAFF-M7JRZtsCErvDO4Tjo8nMvHOcWGsX35-Qe15vPowBAt2VUG8nMM_ey_uXkAClU9mz1M5RraV_wGeCgfT34YjYInwAvHwDZFtsbgt4oOu3lE9sVolxpkcxy8iBnjaFZSpDN85yk9g6Lw26o-KjQDLYM_ASWj0Eb95wHBVTyYytKLTXy1o4z0FxxvJ3dfl8qn4FO-85j4XIv34LINJC3G8a_s3XPKSiaIydqyNcZZdvwq5-pRVPc5jMFrHbTbrn1V2isLBCsybiws-1iOIFhUKRo6VnoB8wOaz0; path=/; secure; HttpOnly
Strict-Transport-Security: max-age=31536000; includeSubDomains, max-age=31536000; includeSubDomains
Transfer-Encoding: chunked
X-Content-Type-Options: application/json
X-Handled-By: Visma-PX.Export/AuthenticationManagerModule
X-Xss-Protection: 1;mode=block

{"message":"An error has occurred.","exceptionMessage":"Error parsing HTTP message header byte 5 of message System.Byte[].","exceptionType":"System.InvalidOperationException","stackTrace":"   at System.Net.Http.HttpContentMessageExtensions.<ReadAsHttpRequestMessageAsyncCore>d__12.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Batch.DefaultHttpBatchHandler.<ParseBatchRequestsAsync>d__14.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Batch.DefaultHttpBatchHandler.<ProcessBatchAsync>d__12.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Batch.HttpBatchHandler.<SendAsync>d__12.MoveNext()"}
6 REPLIES 6
adrianm
PARTNER

by adrianm

I don't use batch in production anywhere. Just have an old test case which I ran when I saw your question. Tested now and it works with both tenant and token. (I get an exception in the response with compression but it is different from yours)

POST: https://integration.visma.net/API/controller/api/v1/$batch
{
	Accept: application/json
	Authorization: <hidden>
	Content-Type: multipart/mixed; boundary="37f3e586-2c20-47da-9679-3214fc428cdd"
	Content-Length: 365
}
--37f3e586-2c20-47da-9679-3214fc428cdd
Content-Type: application/http; msgtype=request

GET /api/v1/salesordertype/SO HTTP/1.1
Host: integration.visma.net


--37f3e586-2c20-47da-9679-3214fc428cdd
Content-Type: application/http; msgtype=request

GET /api/v1/organization HTTP/1.1
Host: integration.visma.net


--37f3e586-2c20-47da-9679-3214fc428cdd--

200: OK{
	Strict-Transport-Security: max-age=31536000; includeSubDomains	Strict-Transport-Security: max-age=31536000; includeSubDomains
	ipp-request-id: c3893b42-4372-4861-a40b-f55cb7724bda
	X-Content-Type-Options: application/json
	Pragma: no-cache
	X-Handled-By: Visma-PX.Export/AuthenticationManagerModule
	Referrer-Policy: origin-when-cross-origin
	Feature-Policy: geolocation 'none'; vr 'none'; payment 'none'; midi 'none'; microphone 'none'; fullscreen 'none'; encrypted-media 'none'; camera 'none'; autoplay 'none';
	X-XSS-Protection: 1;mode=block
	Keep-Alive: timeout=15, max=100
	Connection: Keep-Alive
	Cache-Control: no-cache
	Date: Mon, 16 Oct 2023 13:11:48 GMT
	Set-Cookie: <crumbs>;  expires=Sun, 15-Oct-2023 13:11:48 GMT;  path=/;  secure;  HttpOnly
	Server: Nginx
	Content-Length: 1344
	Content-Type: multipart/mixed; boundary="68427032-2e8d-4e07-8af0-fa58706f906d"
	Expires: -1
}
--68427032-2e8d-4e07-8af0-fa58706f906d
Content-Type: application/http; msgtype=response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"orderType":"SO" ...}
--68427032-2e8d-4e07-8af0-fa58706f906d
Content-Type: application/http; msgtype=response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[{"organizationCd":"1 ...}]
--68427032-2e8d-4e07-8af0-fa58706f906d--

 

omelhus
PARTNER

by omelhus

Alright, thank you for taking time to do the extra tests.

 

Are you using postman, insomnia, or something else? I'm getting the exact same error from both node and httpie, so I'm at a loss at what can be wrong.

 

Looks like I won't be using $batch in production either. Bummer.

Accepted solution
adrianm
PARTNER

by adrianm (Updated ‎16-10-2023 22:12 by adrianm PARTNER )

I am using my own API library so it will not help you but the test looks like this 😀

 

 

var vnclient = new VismaNetClient(new Uri("https://integration.visma.net/API/"));
vnclient.ClientId = "<clientId>";
vnclient.ClientSecret = "<clientSecret>";
//vnclient.Token = "<token>";

var vncontext = new VismaNetContext(vnclient, tenantId: "<tenantId>");
//var vncontext = new VismaNetContext(vnclient, companyId: <companyId>);


using var batchContext = new VismaNetBatchContext(vncontext);
var b1 = batchContext.SalesOrderType.GetSalesOrderTypeByorderTypeAsync("SO");
var b2 = batchContext.SalesOrder.GetOrderByTypeByorderTypeorderNbrAsync("SO", "2000955");

await batchContext.SendBatchAsync(TimeSpan.FromSeconds(20), b1, b2);

Assert.AreEqual("SO", b1.Result.OrderType);
Assert.IsNull(b2.Result);

 

 

 

In my library all requests, batch or not, use the same HttpClient (or actually the same HttpClientHandler) so I can't selectively activate compression (and I want to use compression, at least for non-batch requests).

 

I can of course rewrite it but so far the benefits of batch haven't justified it for me.

 

Batch does not give you a transaction and the parts run sequentially on the server anyway so there is not much  performance difference. Parallel requests are always faster

 

omelhus
PARTNER

by omelhus

Batch does not give you a transaction and the parts run sequentially on the server anyway so there is not much  performance difference. Parallel requests are always faster


Thanks for the insights. It's completely useless then. I'll just send requests in parallell - that works just fine.

adrianm
PARTNER

by adrianm

Same batch works for me so it is not a general problem.

Note that Visma.Net does not support compression in batch requests. Ensure it is not activated at some lower level.

omelhus
PARTNER

by omelhus

Thank you for testing. I cannot believe that compression is still an issue after almost a year.

 

Are you using user context or m2m? I'm testing with a token generated with a tenant id, and it is not working.

 

I can't see that I've enabled compression anywhere in this request.