0

I'm trying to use the Refit library to post a file to my backend using these instructions

But I have not been able to make this work. I found this issue which seems to indicate the same thing I'm doing, but it didn't help: https://github.com/reactiveui/refit/issues/991

//refit api

[Multipart]
[Post("/api/cluster/deploy")]
Task PostDeployAsync([AliasAs("file")] StreamPart stream);

//my backend controller
[HttpPost("deploy"), DisableRequestSizeLimit]
public async Task PostDeployAsync(IFormFile file)
{

//blazor code
<Blazorise.FileEdit Changed="@OnChanged"  />

async Task OnChanged(FileChangedEventArgs e)
{
    foreach (var file in e.Files)
    {
        var fs = file.OpenReadStream();
        await _api.PostDeployAsync(new StreamPart(fs, file.Name, "application/zip", file.Name));

In my controller the IFormFile file is null. What am I doing wrong?

Below is the method I used to verify that the refit part is the problem. With this, the file on the controller is populated correctly.

@inject HttpClient http

var fileContent =
    new StreamContent(file.OpenReadStream(maxFileSize));

fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/zip");

using var content = new MultipartFormDataContent();
content.Add(
    content: fileContent,
    name: "\"files\"",
    fileName: file.Name);

var response =
    await http.PostAsync("api/cluster/deploy", content);
DLeh
  • 23,806
  • 16
  • 84
  • 128
  • your var fs get the file that you upload? – Leandro Toloza Oct 24 '22 at 19:08
  • @LeandroToloza yes sorry had a bad paste (i simplified the code a bit). `fs` is being passed into the `new StreamPart()`, corrected the question. it is working if i use non-refit method to upload – DLeh Oct 24 '22 at 19:09
  • 1
    it's not a solution using Iformfile but you could create a method on your controller with a byte[] as parameter and do something like this with your file! var target = new System.IO.MemoryStream(); / await file.OpenReadStream().CopyToAsync(target); / fileToSendToApi = target.ToArray(); – Leandro Toloza Oct 24 '22 at 19:14
  • 1
    Unfortunately I actually am basically proxy-ing another service that expects it as multi-part. So while I have access to my controller, I want the contract between my controller and the third party one to be the same. So ultimately I want to be able to use the same refit client contract with both my api and the third party one. – DLeh Oct 25 '22 at 13:31

1 Answers1

0

Looks like the problem was the last parameter to the StreamPart. I changed my controller to accept IEnumerable<IFormFile> files and then put that variable name "files" as the final parameter of the StreamPart:

await _api.PostDeployAsync(new StreamPart(fs, file.Name, "application/zip", "files"));


[HttpPost("deploy"), DisableRequestSizeLimit]
public async Task PostDeployAsync(IEnumerable<IFormFile> files)
DLeh
  • 23,806
  • 16
  • 84
  • 128