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)