Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unable to send IFormFile to ASP.Net Core Web API using C# client

I have an ASP.Net Core Web API, with a controller POST method defined like this:

[HttpPost("SubmitFile")]
public async Task<IActionResult> SubmitFile(IFormFile file)
{
}

I have a client-side method to call the API SubmitFile() method, defined like this:

[HttpPost]
public async Task<IActionResult> Index(ICollection<IFormFile> files)
{
     using (var client = new HttpClient())
     {
         client.BaseAddress = new Uri(_options.SiteSpecificUrl);

         foreach (var file in files)
         {
             if (file.Length <= 0)
                 continue;

             var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
             var fileContent = new StreamContent(file.OpenReadStream());
             fileContent.Headers.Add("X-FileName", fileName);
             fileContent.Headers.Add("X-ContentType", file.ContentType);

             var response = await client.PostAsync(_options.WebApiPortionOfUrl, fileContent);
         }
     }

    return View();
}

When the client send is performed, on the server side a break-point in SubmitFile() shows that the file argument is null. How can I correctly send the file? It is important to preserve the server-side API, as I have Swashbuckle/Swagger correctly generating a UI that can send the file.

like image 309
stellaOctangula Avatar asked Jun 16 '17 16:06

stellaOctangula


1 Answers

I've found a couple ways of doing this. Here is the simplest. Note that this is an ASP.Net Core client-side solution:

[HttpPost]
public async Task<IActionResult> Index(ICollection<IFormFile> files)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(_options.SiteSpecificUrl);

        foreach (var file in files)
        {
            if (file.Length <= 0)
                continue;

            var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');

            using (var content = new MultipartFormDataContent())
            {
                content.Add(new StreamContent(file.OpenReadStream())
                {
                    Headers =
                    {
                        ContentLength = file.Length,
                        ContentType = new MediaTypeHeaderValue(file.ContentType)
                    }
                }, "File", fileName);

                var response = await client.PostAsync(_options.WebApiPortionOfUrl, content);
            }
        }
    }
}

This controller method is called from a .cshtml page as follows:

@{
    ViewData["Title"] = "Home Page";
}

<form method="post" asp-action="Index" asp-controller="Home" enctype="multipart/form-data">
    <input type="file" name="files" multiple />
    <input type="submit" value="Upload" />
</form>

This form displays two buttons, "Choose Files", which presents a "select files" dialog, and "Upload", which calls the HomeController.Index method.

like image 89
stellaOctangula Avatar answered Nov 10 '22 14:11

stellaOctangula