The JsonServiceClient
is apart of ServiceStack’s C# Service Clients which is a big part of ServiceStack’s end to end story. From looking at your Web Service example it looks like you’re fighting ServiceStack at multiple points, i.e. your own Response DTO base class instead of a normal concrete DTO using the built-in ResponseStatus, your own error handling instead of using ServiceStack’s built-in Error Handling which automatically converts C# Exceptions into structured HTTP Error Handling, your own Authentication implementation instead of a Custom AuthProvider, your own serialization/deserialization, client library, use of nested classes, etc. There looks like a lot of customization being done here instead of taking advantage of the built-in tested and free functionality in ServiceStack which also means you need to ensure that your custom functionality is implemented and works together correctly.
The issue here is that your HTTP Request for some reason isn’t being recognized as a valid File Upload request in ASP.NET which is indicated by Request.Files.Count == 0
. Out of all the different customization being used, reading the Request Input Stream could have an effect here.
If I were you I’d look at peeling back everything, getting to a working state then adding back your functionality one-by-one to see what’s causing the issue. To provide a starting point I’ve created a new Empty ServiceStack ASP.NET Project and added a normal File Upload example:
public object Post(UploadFile request)
{
if (this.Request.Files.Length == 0)
throw new FileNotFoundException("UploadError", "No such file exists");
var file = this.Request.Files[0];
return new UploadFileResponse
{
Name = file.Name,
FileName = file.FileName,
ContentLength = file.ContentLength,
ContentType = file.ContentType,
Contents = new StreamReader(file.InputStream).ReadToEnd(),
File = request.File,
};
}
That mimics the details you’ve provided in this thread, available on Github at:
Which can be downloaded directly from Github: https://github.com/mythz/FileUploadTest/archive/master.zip
After you hit Ctrl+F5
to run your projects you can run the Unit Tests to see a working example, I’ve added both a normal File Upload:
private const string BaseUrl = "http://localhost:61557/";
[Test]
public void Can_upload_file()
{
var client = new JsonServiceClient(BaseUrl);
var fileInfo = new FileInfo("~/App_Data/file.json".MapProjectPath());
var response = client.PostFile<UploadFileResponse>(
"/UploadFile",
fileToUpload: fileInfo,
mimeType: "application/json");
Assert.That(response.Name, Is.EqualTo("file"));
Assert.That(response.FileName, Is.EqualTo("file.json"));
Assert.That(response.ContentLength, Is.EqualTo(fileInfo.Length));
Assert.That(response.ContentType, Is.EqualTo("application/json"));
Assert.That(response.Contents, Is.EqualTo(fileInfo.ReadAllText()));
Assert.That(response.File, Is.Null);
}
As well as a File Upload with Request DTO to see how you could do either
[Test]
public void Can_upload_file_with_Request()
{
var client = new JsonServiceClient(BaseUrl);
var fileInfo = new FileInfo("~/App_Data/file.json".MapProjectPath());
var response = client.PostFileWithRequest<UploadFileResponse>(
"/UploadFile",
fileToUpload: fileInfo,
request: new UploadFile { File = "Request DTO Property" },
fieldName: "file");
Assert.That(response.Name, Is.EqualTo("file"));
Assert.That(response.FileName, Is.EqualTo("file.json"));
Assert.That(response.ContentLength, Is.EqualTo(fileInfo.Length));
Assert.That(response.Contents, Is.EqualTo(fileInfo.ReadAllText()));
Assert.That(response.File, Is.EqualTo("Request DTO Property"));
}