0

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.

0

1 Answer 1

1

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();
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @Lightman, not specifying content-type helps. Debugging however shows still, Content-Type: multipart/form-data with some large boundary number is sent by postman still. So its really not that the content type was wrong but somehow, even when I used just what postman is sending and specifying it, it didn't work. Swagger still close the app when trying to upload an image. and root folder exists for other reason and works well.
Uploads where the payload is just the raw file contents are not supported in Swagger 2.0, because they are not multipart/form-data. Hi, @Koref ,I found Can I upload files via PUT? from swagger.io. Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.