2

I'm developing a Web API with .Net Core, where I need to allow a client to upload a list of files (mostly images) and save them to the server.

The problem is that when the image is uploaded, and I try to open it from the folder where it was saved, it seems like it's corrupted and its size is not the same as the initial one.

Here is the code of my controller:

[Route("api/TestUpload")]
[Consumes("multipart/form-data")]
public class TestUploadController : Controller
{
    private readonly IHostingEnvironment _env;
    private readonly ApplicationContext _context;

    public TestUploadController(ApplicationContext context, IHostingEnvironment env)
    {
        _context = context;
        _env = env;
    }

    // GET: /<controller>/
    public IActionResult Index()
    {
        return View();
    }

    [HttpPost("upload")]
    public async Task<IActionResult> Post([FromForm]IList<IFormFile> files)
    {
        long size = files.Sum(f => f.Length);

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

        foreach (var formFile in files)
        {
            if (formFile.Length > 0)
            {
                var filePath = Path.Combine(uploads, formFile.FileName);
                using (var fileStream = new FileStream(Path.Combine(uploads, formFile.FileName), FileMode.Create))
                {
                    await formFile.CopyToAsync(fileStream);
                    fileStream.Flush();
                }
            }
        }

        return Ok(new { size });
    }
}

The only files that seem to be uploaded and saved fine are text and html files. I've tried with a single file instead of a list, same thing.

I've tried several code variations and none seem to work, I'm probably doing something wrong but I just can't figure out what it is.

Here is a screenshot of a test with Advanced REST client: ARC screenshot

And here is what I mean by "it seems like it's corrupted": Windows Photo Viewer screenshot

Any help is appreciated!

6
  • Add a byte count to beginning of message. The on receive end extract byte count and read until the entire message is received. Filestream when you read from a File Synchronously the windows operating system puts a null at end of file. When you are reading from a file Async there is no blocking so you return immediately. The await does nothing in this case. Commented Aug 17, 2018 at 10:29
  • Strange, since your image suggest the incomming size is to small. How are you uploading this file? Commented Aug 17, 2018 at 10:30
  • @jdweng But I've tried using just formFile.CopyTo(fileStream); instead of doing it asynchronously but nothing changes. Commented Aug 17, 2018 at 10:52
  • @Stefan Yes, I'm not going beyond the file size limitations as far as I know. I'm using the Adavanced REST client, and choosing multipart/form-data as the content type. Commented Aug 17, 2018 at 10:54
  • I'm not seeing anything obviously wrong in your code. Flush is unecessary and can be removed, but I don't think that's causing the issue. Are you sure the files are good to begin with? Commented Aug 17, 2018 at 13:07

1 Answer 1

1

The are two problems which may cause confusion here:

  1. Media types which are supported by service which define what formats of data can be uploaded correctly to the server.

  2. Format of image uploaded which is different than image stored on source computer since none of image media format is supported by yur WebAPI.

In case like your WebAPI client HTTP POST message contains a payload - image, in HTTP header the Content-Type specifies the format of the message body. This tells the Web API how to parse the contents of the message body. For example, if an HTTP post message to your API contains a PNG image, the POST request might have the following headers:

Content-Length: 95267
Content-Type: image/png

Adding correct media formats attributes to you WebAPI controller class shuld support indicated in them image formats:

[Route("api/TestUpload")]
[Consumes("multipart/form-data")]
[Consumes("image/jpg")]
[Consumes("image/png")]
[Consumes("image/gif")]
public class TestUploadController : Controller
{
}

In the case of any further problems or need to support image formats not available out of box create custom MediaFormatter clas derived from for instance BufferedMediaFormatter and use it in your project.

Sign up to request clarification or add additional context in comments.

1 Comment

I can't add multiple [Consumes] annotations.

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.