44

I am attempting to upload an image using MVC 6; however, I am not able to find the class HttpPostedFileBase. I have checked the GitHub and did not have any luck. Does anyone know the correct way to upload a file in MVC6?

demonplus
  • 5,036
  • 11
  • 41
  • 56
Steven Mayer
  • 561
  • 1
  • 5
  • 18

3 Answers3

60

MVC 6 used another mechanism to upload files. You can get more examples on GitHub or other sources. Just use IFormFile as a parameter of your action or a collection of files or IFormFileCollection if you want upload few files in the same time:

public async Task<IActionResult> UploadSingle(IFormFile file)
{
    FileDetails fileDetails;
    using (var reader = new StreamReader(file.OpenReadStream()))
    {
        var fileContent = reader.ReadToEnd();
        var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
        var fileName = parsedContentDisposition.FileName;
    }
    ...
}

[HttpPost]
public async Task<IActionResult> UploadMultiple(ICollection<IFormFile> files)
{
    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));
        }
        ...
    }
}

You can see current contract of IFormFile in asp.net sources. See also ContentDispositionHeaderValue for additional file info.

Vadim Martynov
  • 6,849
  • 5
  • 28
  • 39
  • I am trying to convert image to byte array, but there is no method of readbytes or equivalent in stream reader object. And binary reader is not working now as ifileform object has no input stream property – It's a trap Jun 21 '16 at 17:32
  • @RachitGupta what is your scenario? Why do you need to convert image to `byte[]`. What actually type do you use? Hope next link will be helpful for you. http://stackoverflow.com/questions/3801275/how-to-convert-image-in-byte-array – Vadim Martynov Jun 22 '16 at 13:11
  • 1
    You could improve this answer by mentioning which 'using' is required, and whether a project reference is necessary - since dotnetcore doesn't include lots of things by default, and they have to be explicitly added. Maybe Visual Studio will automatically add the right references, but Visual Studio Code cannot. – Alex White Mar 04 '17 at 23:45
20

There is no HttpPostedFileBase in MVC6. You can use IFormFile instead.

Example: https://github.com/aspnet/Mvc/blob/dev/test/WebSites/ModelBindingWebSite/Controllers/FileUploadController.cs

Snippet from the above link:

public FileDetails UploadSingle(IFormFile file)
{
    FileDetails fileDetails;
    using (var reader = new StreamReader(file.OpenReadStream()))
    {
        var fileContent = reader.ReadToEnd();
        var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
        fileDetails = new FileDetails
        {
            Filename = parsedContentDisposition.FileName,
            Content = fileContent
        };
    }

    return fileDetails;
}
Matt DeKrey
  • 10,592
  • 4
  • 48
  • 67
Kiran Challa
  • 53,599
  • 15
  • 167
  • 151
  • 1
    I am using Beta 7, But i am getting IFormFile is null when ajax request. Also FileDetails is not found in my case.. Will you guide. – Karthick Dec 08 '15 at 17:54
3

I was searching around for quite a while trying to piece this together in .net core and ended up with the below. The Base64 conversion will be next to be done so that the retrieval and display is a little easier. I have used IFormFileCollection to be able to do multiple files.

[HttpPost]
    public async Task<IActionResult> Create(IFormFileCollection files)
    {

        Models.File fileIn = new Models.File();
        if(model != null && files != null)
        {
            foreach (var file in files)
            {
                if (file.Length > 0)
                {
                  var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');

                        byte[] fileBytes = null;
                        using (var fileStream = file.OpenReadStream())
                        using (var ms = new MemoryStream())
                        {
                            fileStream.CopyTo(ms);
                            fileBytes = ms.ToArray();
                            //string s = Convert.ToBase64String(fileBytes);
                            // act on the Base64 data
                        }


                        fileIn.Filename = fileName;
                        fileIn.FileLength = Convert.ToInt32(file.Length);
                        fileIn.FileType = file.ContentType;
                        fileIn.FileTypeId = model.FileTypeId;
                        fileIn.FileData = fileBytes;
                        _context.Add(fileIn);
                        await _context.SaveChangesAsync();
                }
            }
        }
        return View();
    }

EDIT

And below is return of files to a list and then download.

public JsonResult GetAllFiles()
    {

        var files = _context.File
            .Include(a => a.FileCategory)
            .Select(a => new
            {
                id = a.Id.ToString(),
                fileName = a.Filename,
                fileData = a.FileData,
                fileType = a.FileType,
                friendlyName = a.FriendlyName,
                fileCategory = a.FileCategory.Name.ToLower()
            }).ToList();

       return Json(files);
    }

    public FileStreamResult DownloadFileById(int id)
    {
        // Fetching file encoded code from database.
        var file = _context.File.SingleOrDefault(f => f.Id == id);
        var fileData = file.FileData;
        var fileName = file.Filename;

        // Converting to code to byte array
        byte[] bytes = Convert.FromBase64String(fileData);

        // Converting byte array to memory stream.
        MemoryStream stream = new MemoryStream(bytes);

        // Create final file stream result.
        FileStreamResult fileStream = new FileStreamResult(stream, "*/*");

        // File name with file extension.
        fileStream.FileDownloadName = fileName;
        return fileStream;
    }
K7Buoy
  • 836
  • 2
  • 12
  • 20
  • Another option: public async Task Create(), and then the files can be retrieved by: var files = HttpContext.Request.Form.Files; – JoshYates1980 Jan 29 '17 at 16:28
  • I tried to edit my comment above, but SOF said I exceeded 5 minutes. Here is another option: public JsonResult Create(), and then the files can be retrieved by: var files = HttpContext.Request.Form.Files; Both options work sending multiple files to the server. – JoshYates1980 Jan 29 '17 at 17:52