reactiveui / refit

The automatic type-safe REST library for .NET Core, Xamarin and .NET. Heavily inspired by Square's Retrofit library, Refit turns your REST API into a live interface.
https://reactiveui.github.io/refit/
MIT License
8.6k stars 746 forks source link

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

Open dev-vkagrawal opened 4 years ago

dev-vkagrawal commented 4 years ago

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.

natelaff commented 3 years ago

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)
dev-vkagrawal commented 3 years ago

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?

natelaff commented 3 years ago

I use something like

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

dev-vkagrawal commented 3 years ago

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.

natelaff commented 3 years ago

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.

dev-vkagrawal commented 3 years ago

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.

MohamedErfan9 commented 2 years ago

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

DrLeh commented 2 years ago

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?

ordonezgrubi commented 1 year ago

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.

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

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

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

Strypper commented 1 year ago

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

Fram90 commented 1 year ago

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

alexx-grand commented 1 year ago

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