refit icon indicating copy to clipboard operation
refit copied to clipboard

[BUG] How to upload IFormFile within an object model using refit in .Net core

Open dev-vkagrawal opened this issue 5 years ago • 12 comments

Hi,

Can anyone tell how to upload file of type IFormFile within an object in .Net Core. If model contains IFormFile type then it is not working. I have used [Multipart] attribute and can't replace IFormFile to something else as I have used that across entire project.

dev-vkagrawal avatar Oct 30 '20 15:10 dev-vkagrawal

This is what I do...

API Client

    [Multipart]
    [Post("/me/picture")]
    Task<ApiResponse<object>> UploadPictureAsync([AliasAs("file")] StreamPart stream);

API signature

    [HttpPost("picture")]
    public async Task<IActionResult> PostPictureAsync(IFormFile file)

natelaff avatar Jan 27 '21 16:01 natelaff

Hi natelaff, can you please tell me how would hit your refit method from .net core mvc action method and what if I have object to pass to web api and within that I have IFormFile property rather than calling API directly with single IFormFile property?

dev-vkagrawal avatar Jan 29 '21 18:01 dev-vkagrawal

I use something like

var file = Request.Form.Files[0]; await _client.UploadPictureAsync(new Refit.StreamPart(file.OpenReadStream(), file.FileName, file.ContentType));

natelaff avatar Jan 29 '21 21:01 natelaff

But would it require me to change IFormFile in my api controller? How I can pass new Refit.StreamPart(...) as property of my existing model. I don't wanna call separate api with just image rather I wanna pass it as a whole object within my original model.

dev-vkagrawal avatar Feb 05 '21 18:02 dev-vkagrawal

No, you can see my definitions of the client and the API method above. I use IFormFile in the API, and StreamPart in the client.

EDIT: Oh, I see what you're saying. I don't know about that, I don't use uploads in a complex model. I have a separate Image upload API then post that URL with my object.

natelaff avatar Feb 05 '21 18:02 natelaff

Ok thanks natelaff, I think I am left with either two API calls or convert IFormFile into byte[] in model. If you know any other solution then please let me know.

dev-vkagrawal avatar Feb 05 '21 18:02 dev-vkagrawal

@dev-vkagrawal please if you solve this issue please share with me

MohamedErfan9 avatar Apr 19 '22 09:04 MohamedErfan9

I have still not been able to make this work:

//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(stream, file.Name, "application/zip", file.Name));

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

DrLeh avatar Oct 24 '22 18:10 DrLeh

Im on the same boat. I have a scenario where I need to send data to an api that consumes a model with an List<IFormFile>.

public class Class1{ [AliasAs("Name")] public string Name { get; set; } [AliasAs("Files")] public IEnumerable<ByteArrayPart> Files { get; set; } }

[Multipart] [Post("/private/api-call")] Task<Class2> Post(Class1 data);

The files dont seem to work unless I do a Post([AliasAs("Files")] IEnumerable<ByteArrayPart> files);

ordonezgrubi avatar Nov 18 '22 00:11 ordonezgrubi

Hi any update on supporting upload complex object which have IFormFile in it ?

Strypper avatar Feb 23 '23 11:02 Strypper

Same problem here. IFormFile is a part of another model. Doesn't work with refit.

Fram90 avatar Apr 17 '23 14:04 Fram90

@DrLeh I use FromForm attribute and it works well [FromForm(Name = "file")] IFormFile formFile

alexx-grand avatar May 18 '23 07:05 alexx-grand