New

Thank you for adding this item to Sage City Ideas Hub.  Open for voting.

Sage 200 API Unable to send large requests

The Sage 200 APIClientLibrary fails to generate the necessary HMAC signature when the request payload is large.  I am trying to post an Sales Invoice with approximately 300 line items.

It appears that when generating the signature the APIClientLibrary uses System.Uri.EscapeDataString in order to create a hash of the entire content of the body.  It appears that in .NET framework v4.5 the limit is 32765 bytes or 65519 bytes in .NET >4.5.

Here is a workaround that you could implement to avoid this issue: https://stackoverflow.com/questions/6695208/uri-escapedatastring-invalid-uri-the-uri-string-is-too-long

To clarify this is not the URI of the HTTP request (POST) URI that is too long (the URI remains https://api.columbus.sage.com/uk/sage200/accounts/v1/sales_invoices which is a sensible length), this error is occurring before the request is even made as it is unable to generate the signature.

Example stack trace:

Invalid URI: The Uri string is too long.
at System.UriHelper.EscapeString(String input, Int32 start, Int32 end, Char[] dest, Int32& destPos, Boolean isUriString, Char force1, Char force2, Char rsvd)
at System.Uri.EscapeDataString(String stringToEscape)
at APIClientLibrary.SignatureGenerator.NormalizeParams(String httpMethod, Uri url, String body)
at APIClientLibrary.SignatureGenerator.GetBaseString(String httpMethod, Uri url, String body, String nonce)
at APIClientLibrary.SignatureGenerator.GenerateSignature(String httpMethod, Uri url, String body, String secretKey, String token, String nonce)
at APIClientLibrary.SigningMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.PostAsync(Uri requestUri, HttpContent content, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.PostAsync(String requestUri, HttpContent content)
at APIClientLibrary.APIClient.<PostAsync>d__33.MoveNext()
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at APIClientLibrary.APIClient.Post(String url, String body)