100

Here is my code:

 public async Task<IActionResult> Index(ICollection<IFormFile> files)
 {
    foreach (var file in files)
        uploaddb(file);   

    var uploads = Path.Combine(_environment.WebRootPath, "uploads");
    foreach (var file in files)
    {
        if (file.Length > 0)
        {
            var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');

            await file.SaveAsAsync(Path.Combine(uploads, fileName));
        }
    }
}

Now I am converting this file into byte array using this code:

var filepath = Path.Combine(_environment.WebRootPath, "uploads/Book1.xlsx");
byte[] fileBytes = System.IO.File.ReadAllBytes(filepath);
string s = Convert.ToBase64String(fileBytes);

And then I am uploading this code into my nosql database.This is all working fine but the problem is i don't want to save the file. Instead of that i want to directly upload the file into my database. And it can be possible if i can just convert the file into byte array directly without saving it.

public async Task<IActionResult> Index(ICollection<IFormFile> files)
{
    foreach (var file in files)
        uploaddb(file);   
    var uploads = Path.Combine(_environment.WebRootPath, "uploads");
    foreach (var file in files)
    {
        if (file.Length > 0)
        {
            var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');

///Code to Convert the file into byte array
}
Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Kalp
  • 1,284
  • 2
  • 8
  • 16
  • Um... so what exactly is the problem? – Kevin Apr 05 '16 at 16:30
  • *file.OpenReadStream()* look for the documentation of IFormFile.OpenReadStream – Gusman Apr 05 '16 at 16:32
  • When you originally saved the file, what form was it in? However you had it in memory, it should have already been a byte array, or convertible to a byte array. We would need to see how you are obtaining the file in the first place, and how you are saving it. – Kevin Apr 05 '16 at 16:33

4 Answers4

230

As opposed to saving the data as a string (which allocates more memory than needed and might not work if the binary data has null bytes in it), I would recommend an approach more like

foreach (var file in files)
{
  if (file.Length > 0)
  {
    using (var ms = new MemoryStream())
    {
      file.CopyTo(ms);
      var fileBytes = ms.ToArray();
      string s = Convert.ToBase64String(fileBytes);
      // act on the Base64 data
    }
  }
}

Also, for the benefit of others, the source code for IFormFile can be found on GitHub

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
erdomke
  • 4,980
  • 1
  • 24
  • 30
  • you could shorten the code by using the copy functions on IFormFile themselve. using (var stream = new MemoryStream()) { formFile.CopyTo(stream); return stream.ToArray(); } – Bosken85 Sep 19 '17 at 09:26
  • @Bosken85 Good catch! I updated the example to reflect your recommendations. – erdomke Sep 19 '17 at 17:19
  • 8
    You can also use `file.CopyToAsync(ms)` now. – David B Jan 31 '18 at 08:28
  • Any way I can copy only the first 20 bytes or so to the memory stream and byte array? Only need those to check the file signature – kanpeki Oct 18 '19 at 13:12
  • 2
    Something to the effect of the following should help you out. `using (var stream = file.OpenReadStream()) { var buffer = new byte[20]; stream.Read(buffer, 0, 20); }` – erdomke Oct 18 '19 at 17:02
  • @erdomke why do we need file.CopyTo(ms);? – Roxy'Pro Nov 15 '19 at 20:11
  • @Roxy'pro That line reads the file contents into a MemoryStream (backed by a byte array) so that you can convert the byte array to base64. – erdomke Nov 17 '19 at 04:20
56

You can just write a simple extension:

public static class FormFileExtensions
{
    public static async Task<byte[]> GetBytes(this IFormFile formFile)
    {
        await using var memoryStream = new MemoryStream();
        await formFile.CopyToAsync(memoryStream);
        return memoryStream.ToArray();
    }
}

Usage

var bytes = await formFile.GetBytes();
var hexString = Convert.ToBase64String(bytes);
Rookian
  • 19,841
  • 28
  • 110
  • 180
6

You can use the following code to convert it to a byte array:

foreach (var file in files)
{
   if (file.Length > 0)
    {
      var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
      using (var reader = new StreamReader(file.OpenReadStream()))
      {
        string contentAsString = reader.ReadToEnd();
        byte[] bytes = new byte[contentAsString.Length * sizeof(char)];
        System.Buffer.BlockCopy(contentAsString.ToCharArray(), 0, bytes, 0, bytes.Length);
      }
   }
}
Cat_Clan
  • 352
  • 2
  • 9
-1

You can retrieve your file by using the Request.Form already implemented (as image for instance) :

var bytes = new byte[Request.Form.Files.First().Length];
var hexString = Convert.ToBase64String(bytes);

Hope it help

harili
  • 406
  • 9
  • 24