Koref Koref
Koref Koref

Reputation: 330

Unable upload image file in ASP.NET Core Web API - POST method

I was trying to upload a single image file. Sample code is as follows:

        /// <summary>
        /// Uploads a single image document 
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("{id}/scan-doc-image")]
        //[RequestFormLimits(ValueLengthLimit = int.MaxValue, MultipartBodyLengthLimit = int.MaxValue)]
        public async Task<ActionResult> UploadImage(int id, IFormFile file)
        {
            // more validation goes here.
            if (file == null)
            {
                return BadRequest();
            }

            // save image if any
            if (file.Length > 0)
            {
                var uploads = Path.Combine(_envirnment.WebRootPath, "uploads");

                using (var fileStream = new FileStream(Path.Combine(uploads, file.FileName), FileMode.Create))
                {
                    await file.CopyToAsync(fileStream);
                }
            }

            return Ok();
        }

Here is what I noticed:

  1. Making a call to this API automatically STOPS the service. I tried many many times and it always shuts it down. It didn't stop the service when I make other API calls. Just FYI

  2. I tried making a call from POSTMAN as well. This time, it didn't close the service but I keep getting errors: Failed to read the request form. Missing content-type boundary. Note that, I am specifing Content-Type as multipart/form-data. And when I specify the boundary a number less than max, it still errors. Even when I uncomment the RequestFormLimit attribute you see above, it didn't help either.

So what I am missing here? All I need it to upload a single image file.

Upvotes: 0

Views: 4484

Answers (1)

Michael Wang
Michael Wang

Reputation: 4022

I tried making a call from POSTMAN as well. This time, it didn't close the service but I keep getting errors: Failed to read the request form. Missing content-type boundary. Note that, I am specifing Content-Type as multipart/form-data. And when I specify the boundary a number less than max, it still errors. Even when I uncomment the RequestFormLimit attribute you see above, it didn't help either.

enter image description here There is no need to add a Content-Type header manually. You are overriding the value set by Postman. Just select form-data in POST request and send your request to see if it works. No need to set header when form-data is posted. Just remove the Content-Type and upload as below.

enter image description here





Note for the path which may causes error

If you are using Web API project, you will get null in _envirnment.WebRootPath. There is no wwww directory in Web API project.

enter image description here

Solution

Change WebRootPath

        var uploads = Path.Combine(_envirnment.WebRootPath, "uploads");

to ContentRootPath

        var uploads = Path.Combine(_envirnment.ContentRootPath, "uploads");

Test

enter image description here

Codes of controller

If the specified folder "uploads" does not exist, create it firstly , and then save file to this folder. If the folder already exists, just save the file in it.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace WebAPIDemos.Controllers
{

    [ApiController]
    [Route("[controller]")]
    public class FileController : ControllerBase
    {
        private readonly IWebHostEnvironment _envirnment;

        public FileController(IWebHostEnvironment appEnvironment)
        {
            _envirnment = appEnvironment;
        }

        [HttpPost]
        [Route("{id}/scan-doc-image")]
        //[RequestFormLimits(ValueLengthLimit = int.MaxValue, MultipartBodyLengthLimit = int.MaxValue)]
        public async Task<ActionResult> UploadImage(int id, IFormFile file)
        {
            // more validation goes here.
            if (file == null)
            {
                return BadRequest();
            }

            // save image if any
            if (file.Length > 0)
            {
                //var uploads = Path.Combine(_envirnment.WebRootPath, "uploads");
                var uploads = Path.Combine(_envirnment.ContentRootPath, "uploads");

                var destinationDirectory = new DirectoryInfo(uploads);

                if (!destinationDirectory.Exists)
                    destinationDirectory.Create();


                using (var fileStream = new FileStream(Path.Combine(uploads, file.FileName), FileMode.Create))
                {
                    await file.CopyToAsync(fileStream);
                }
            }

            return Ok();
        }
    }
}

Upvotes: 1

Related Questions