Uploading a file through indicium basic method returns Bad Request

  • 27 July 2021
  • 4 replies
  • 208 views

Hi all,

First time poster here. I am a newly hired developer at my organisation (I do not have my own TW Community account at the time of writing, which is why I am writing from this account). Prior to my position at this organisation, I have no experience using either Indicium or Thinkwise as a platform so, my apologies if anything is at all unclear in this question.

Now for my actual issue: I am attempting to POST an encoded image file (most probably JPEGs from client side) to Indicium Basic. The image is quite small, usually no more than 500KB, yet with each requests a 400 Bad Request error is returned by Indicium. The full response is as follows:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML>

<HEAD>
<TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii">
</HEAD>

<BODY>
<h2>Bad Request - Invalid Verb</h2>
<hr>
<p>HTTP Error 400. The request verb is invalid.</p>
</BODY>

</HTML>

Search results on StackOverflow and other sites about the response indicate either invalid cookies or cache in the browser getting in the way or, in case of a file upload, a restriction on file size.

I have tried deleting cookies and cache multiple times to no avail, and my colleagues are unaware of any file size restriction on either Indicium itself or the IIS instance on which it runs.

The request I am trying to send is as below:

{
"subsidiary_id": 1,
"branch_id": 3,
"work_order_id": 326,
"work_order_document_id": null,
"document": {
"FilePath": "test.jpg",
"FileName": "test.jpg",
"File": "<base64_encoded_file_string_here>"
},
"comment": "null",
"document_class_id": 38,
"insert_user": null,
"insert_timestamp": null,
"update_user": null,
"update_timestamp": null
}

If my colleague tries this same body in his Postman client, it creates the document without issue. However, soon as I try it in either my own Postman client or in the API, it returns the above Bad Request response.

Should it be of any help, below is the C# code in the API which makes the request to Indicium using the FlurlHttp library:

// <base_url>/sf/<application>/work_order_document
IFlurlRequest postDocument = _optionsMonitor.CurrentValue.GetUriToBranch()
.AppendPathSegment("work_order_document")
.WithBasicAuth(
_httpContextAccessor.HttpContext?.Items["dms-user"]?.ToString() ??
throw new UnauthorizedException("Username could not be found in the request.", null),
_httpContextAccessor.HttpContext?.Items["dms-pass"]?.ToString() ??
throw new UnauthorizedException("Password could not be found in the request", null));

try
{
IFlurlResponse response = await postDocument.PostJsonAsync(new
{
subsidiary_id = document.SubsidiaryId,
branch_id = document.BranchId,
work_order_id = document.WorkOrderId,
document = document.Document, // { FilePath: "test.jpg", FileName: "test.jpg", File: "<base64_encoded_file_string_here>" }
comment = document.Comment,
document_class_id = document.DocumentClassId
}, ct);

return response.ResponseMessage.IsSuccessStatusCode;
}
catch (FlurlHttpException e)
{
throw await HandleErrorAsync(e);
}

I am unsure where to go from here, none of the “common” problems I found seem to resolve this issue. Am I missing something in the request? Or should I specify some specific header for these types of requests?

 

Any help is greatly appreciated. If anything is at all vague or unclear, please do not hesitate to ask!

Many thanks in advance!


4 replies

Userlevel 6
Badge +4

Hello Arno,

The error that you’re receiving is not coming from Indicium, I think it is probably coming from IIS. It looks like your request is invalid in some way, but it’s not immediately clear why. Does it work if you try a POST request without a file in it? If no, does it work if you try to hard code the base URL? It’s hard for me to tell what the value of “_optionsMonitor.CurrentValue.GetUriToBranch()” might be.

I installed the Flurl.Http package myself to try it out and I had no issues uploading a file. I used the following C# code:

IFlurlRequest request = new FlurlRequest(new Flurl.Url("https://localhost/indicium/iam/itst"))
.AppendPathSegment("filestorage_file_system")
.WithBasicAuth("username", "password");

try
{
IFlurlResponse response = await request.PostJsonAsync(new
{
file_system_file = new { FileName = "test.jpg", File = "BASE64 STRING HERE" }
});

Console.WriteLine($"Success: {response.ResponseMessage.IsSuccessStatusCode}");
}
catch (FlurlHttpException e)
{
Console.WriteLine(e.Message);
}

I hope this helps. Let me know if you have more information.

Hello Arno,

The error that you’re receiving is not coming from Indicium, I think it is probably coming from IIS. It looks like your request is invalid in some way, but it’s not immediately clear why. Does it work if you try a POST request without a file in it? If no, does it work if you try to hard code the base URL? It’s hard for me to tell what the value of “_optionsMonitor.CurrentValue.GetUriToBranch()” might be.

I installed the Flurl.Http package myself to try it out and I had no issues uploading a file. I used the following C# code:

IFlurlRequest request = new FlurlRequest(new Flurl.Url("https://localhost/indicium/iam/itst"))
.AppendPathSegment("filestorage_file_system")
.WithBasicAuth("username", "password");

try
{
IFlurlResponse response = await request.PostJsonAsync(new
{
file_system_file = new { FileName = "test.jpg", File = "BASE64 STRING HERE" }
});

Console.WriteLine($"Success: {response.ResponseMessage.IsSuccessStatusCode}");
}
catch (FlurlHttpException e)
{
Console.WriteLine(e.Message);
}

I hope this helps. Let me know if you have more information.


Hi there Vincent,

 

Thank you for the swift reply!

It does appear to be coming from IIS. POST requests without an actual file do go through, both in Postman and in the API.

The hardcoded url is http:\\<local_dev_server>/indicium/sf/<branch>/work_order_document. Everything before “work_order_document” is coming from the “_optionsMonitor.CurrentValue.GetUriToBranch()” call.

I see in your code snippet that you do not specify the FilePath parameter in the request body. Could it be that DMS is trying to look for a valid and/or existing (physical) file path on the server to save the file to? And that it is now failing because it either cannot find the specified path or it already exists somewhere on the server?

Thanks again for the help!

Userlevel 6
Badge +4

Hello Arno,

I tested my request on Indicium Universal, not Indicium Basic, that’s why I’m not supplying the FilePath property. I don’t expect this to be of any consequence for the issue at hand though, because I don’t think that the request even reaches Indicium in your case.

If the FilePath would be the issue, you would receive a different response than the one you’re getting. Furthermore, you would also see the same error when using that request body in Postman.

It’s hard to say what the issue is, I don’t necessarily see anything wrong with the code that you have posted. At the very least I can tell you that it is not an issue with Indicium, it is an issue with the request that’s being sent. The error suggests that the request is not arriving at IIS with a “POST” verb, but rather with some kind of unknown HTTP verb, causing it to be blocked. This is inexplicable however since you’re using the PostJsonAsync method.

I’m afraid that I can’t be more helpful than this without seeing the actual HTTP request that is sent to IIS. Perhaps you can capture the HTTP request using a tool like Fiddler.

Userlevel 3
Badge +2

Hi Vincent,

We have found the issue. The filename in the POST we have tried contained a space and a colon.

Without these invalid characters the POST to Indicium succeeded.

Thanks for your help!

Reply