Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# read IFormFile into byte[]

I am trying to read an IFormFile received from a HTTP POST request like this:

 public async Task<ActionResult> UploadDocument([FromForm]DataWrapper data)
    {
        IFormFile file = data.File;
        string fileName = file.FileName;
        long length = file.Length;
        if (length < 0)
            return BadRequest();
        using FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate);
        byte[] bytes = new byte[length];
        fileStream.Read(bytes, 0, (int)file.Length);

        ...

    }

but something is wrong, after this line executes:

fileStream.Read(bytes, 0, (int)file.Length);

all of the elements of bytes are zero.

Also, the file with the same name is created in my Visual Studio project, which I would prefer not to happen.

like image 222
Eutherpy Avatar asked Dec 23 '22 20:12

Eutherpy


2 Answers

You can't open an IFormFile the same way you would a file on disk. You'll have to use IFormFile.OpenReadStream() instead. Docs here

public async Task<ActionResult> UploadDocument([FromForm]DataWrapper data)
{
    IFormFile file = data.File;

    long length = file.Length;
    if (length < 0)
        return BadRequest();

    using var fileStream = file.OpenReadStream();
    byte[] bytes = new byte[length];
    fileStream.Read(bytes, 0, (int)file.Length);

}

The reason that fileStream.Read(bytes, 0, (int)file.Length); appears to be empty is, because it is. The IFormFile.Filename is the name of the file given by the request and doesn't exist on disk.

like image 88
phuzi Avatar answered Jan 08 '23 02:01

phuzi


Your code's intent seems to be to write to a FileStream, not a byte buffer. What it actually does though, is create a new empty file and read from it into an already cleared buffer. The uploaded file is never used.

Writing to a file

If you really want to save the file, you can use CopyTo :

using(var stream = File.Create(Path.Combine(folder_I_Really_Want,file.FileName))
{
    file.CopyTo(stream);
}

If you want to read from the uploaded file into a buffer without saving to disk, use a MemoryStream. That's just a Stream API buffer over a byte[] buffer. You don't have to specify the size but that reduces reallocations as the internal buffer grows.

Reading into byte[]

Reading into a byte[] through MemoryStream is essentially the same :

var stream = new MemoryStream(file.Length);
file.CopyTo(stream);
var bytes=stream.ToArray();
like image 44
Panagiotis Kanavos Avatar answered Jan 08 '23 03:01

Panagiotis Kanavos