I had written an .net MAUI application for my own to work with an third Party API based Application.
Inside the application there is a file picker to get the file.
private async void file_Clicked(object sender, EventArgs e)
{
var result = await FilePicker.PickAsync(new PickOptions
{
PickerTitle = "Datei hochladen ..."
});
if (result == null)
return;
var stream = await result.OpenReadAsync();
searchAndReplaceViewModel.ReplaceFile = stream;
searchAndReplaceViewModel.ReplaceFileName = result.FileName;
file.Text = result.FileName;
file.BackgroundColor = Colors.LightGreen;
}
in my viewmodel I save the Stream to an object and later on there is the function call to my RestClient:
public object ReplaceFile { get; internal set; }
// A lot of code between
[RelayCommand]
async Task UploadFile(dtoObjectsBase doc)
{
if (IsLoading) return;
try
{
if(App.SearchAndReplaceService.UploadFile(doc, (BufferedStream)ReplaceFile, ReplaceFileName))
{
await Shell.Current.DisplayAlert("Erfolgreich", "Upload Erfolgreich", "Ok");
}
}
catch (Exception ex)
{
Debug.WriteLine($"Unable to Upload File: {ex.Message}");
await Shell.Current.DisplayAlert("Error", "Fehler beim Hochladen der Datei", "Ok");
}
finally
{
IsLoading = false;
}
}
Here is the function called above (There is a function from my service class between, but that shouldn't matter. This is the reason for different parameters and Method names.):
public Operation<FileUploadResponse> FileUpload(BufferedStream file, Guid guid, string filename)
{
Operation<FileUploadResponse> fileUpload = new();
FileUpload fileUploadRequest = new()
{
Guid = guid,
RequestStream = file.UnderlyingStream
};
try
{
var options = new RestClientOptions(Settings.Server)
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest(ApiPaths.FileUpload + "?guid=" + guid.ToString(), Method.Post);
request.AddHeader("Content-Type", "multipart/form-data");
//request.AddFile("MyfactoryImport", );
byte[] data = new byte[file.Length];
file.Read(data, 0, (int)file.Length);
request.AlwaysMultipartFormData = true;
//request.AddFile("RequestStream", data, RestSharp.ContentType.Binary);
request.AddFile(filename, data, RestSharp.ContentType.Binary);
fileUpload.Value = JsonConvert.DeserializeObject<FileUploadResponse>(client.Execute(request).Content);
fileUpload.Success = true;
//fileUpload.Value = APICall<FileUpload, FileUploadResponse>(fileUploadRequest, ApiPaths.FileUpload);
}
catch (Exception ex)
{
fileUpload.ErrorMsg = "Fehler bei der API Abfrage: " + ex.Message;
}
return fileUpload;
}
The Restsharp.Response Status Code is "InternalServerError". The Application Log of the API Endpoint logs the following:
HandleFileUpload (general) failed for guid 8f5ae2b3-39e0-41b8-bc18-b60c2b75fc26 | (null) | (ID:(null) System:(null)) System.ApplicationException: Cannot perform file upload. Start boundary not found.
With Postman the upload is no problem, so I don't know what I am making wrong. I think I am handling the stream on the wrong way, but I don't know how to handle it better.
If I try with Postman, the upload works. Postman generated the following Code for Restsharp:
var options = new RestClientOptions("")
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("https://servername/instance/services/fileupload?guid=6e813e27-bee8-4359-a046-04437365c903", Method.Post);
request.AlwaysMultipartFormData = true;
request.AddFile("file", "dOLC4eFA4/temp.pdf");
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
The API documentation of the application where I try to Upload only says the following:
POST /server/services/fileupload HTTP/1.1
Host: localhost
Accept: application/json
Content-Type: application/json
Content-Length: length
{"Guid":"00000000000000000000000000000000"}
I solved it by using an older RestSharp Version (106.15.0 instead of 110.2.0) I would prefer to use a newer version but for the moment this solution is fine for me.