4

In my ASP.NET MVC project, I am trying to post image from Controller action method to API controller method. Plan is to leverage this API to other clients to use to upload images.

I am able to successfully hit the API Post method from Controller Action method, but am not able to pass the image object.

Here is my HomeController.cs Upload Action Method

[HttpPost]
public async Task<ActionResult> Upload(FormCollection formCollection)
{
    var baseUri = "http://localhost/api/Process";

    HttpPostedFileBase file = Request?.Files[0];

    if (file == null || (file.ContentLength <= 0) || string.IsNullOrEmpty(file.FileName))
        return new EmptyResult();

    string fileName = file.FileName;
    byte[] fileBytes = new byte[file.ContentLength];

    HttpContent stringContent = new StringContent(fileName);
    HttpContent fileStreamContent = new StreamContent(file.InputStream);
    HttpContent bytesContent = new ByteArrayContent(fileBytes);

    using (var formDataContent = new MultipartFormDataContent())
    {
        formDataContent.Add(stringContent, "fileName", fileName);
        formDataContent.Add(fileStreamContent, "inputStream", fileName);
        formDataContent.Add(bytesContent, "fileBytes", fileName);
        using (var httpClient = new HttpClient())
        {
            formDataContent.Headers.ContentType =
                MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");

            var response = await httpClient.PostAsync(baseUri, formDataContent);
            var content = await response.Content.ReadAsStringAsync();
           //Handle the response
        }
    }
    return View("Result");
}

In my Process controller which is inheriting from ApiController, I have the following Post method

[HttpPost]
public async Task<string> Post([FromBody]MultipartFormDataContent formDataContent)
{
    Task<string> imageContent = Request.Content.ReadAsStringAsync();
    string body = imageContent.Result;
    ImageResponse imageResponse = null;
    //.................
    //.................
    return someValue
}

Here parameter formDataContent is always null and Request.Content.ReadAsStringAsync() is empty

Nkosi
  • 235,767
  • 35
  • 427
  • 472
HaBo
  • 13,999
  • 36
  • 114
  • 206

1 Answers1

4

Try sending from the Controller like this

//...other code removed for brevity

using (var form = new MultipartFormDataContent()) {

    var stringContent = new StringContent("fileToUpload");
    form.Add(stringContent, "fileToUpload");

    var streamContent = new StreamContent(file.InputStream);
    streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse(file.ContentType);
    streamContent.Headers.ContentLength = file.ContentLength;
    streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") {
        Name = "fileToUpload",
        FileName = file.FileName
    };
    form.Add(streamContent);

    using (var httpClient = new HttpClient()) {

        var response = await httpClient.PostAsync(baseUri, form);

        //...other code removed for brevity
    }
}

And then process it in the ApiController by extracting the information sent ...

[HttpPost]
public async Task<IHttpActionResult> Post() {
    var content = Request.Content;
    //get file name from content disposition
    var fileName = content.Headers.ContentDisposition.FileName;
    //Get file stream from the request content
    var fileStream = await content.ReadAsStreamAsync();

    //...other code removed for brevity

    return Ok();
}

Referenced this answer : Upload image using HttpClient

Community
  • 1
  • 1
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • 1
    PLEASE never post anything with using(var client = new HttpClient()) --> https://stackoverflow.com/a/54707165/1498669 – Bernhard Jun 28 '21 at 10:21