File Upload in ASP.NET Core MVC

Danh Luu | 3/29/2022 3:43:15 AM

 Trong bài viết này, ta sẽ nói về việc làm sao có thể upload ảnh lên website, Upload lên database hoặc Upload lên server.

Đầu tiên, cần tạo 1 dự án Asp.net core MVC

File Model

Chúng ta sẽ tạo ra 2 models, 1 model để lưu file vào database, 1 cái để lưu file lên server

Vì 2 model này đều có các điểm chung nên ta sẽ tạo 1 cái model để cho 2 cái kế thừa lại những điểm chung đó

1. File Path: Thuộc tính để lưu đuòng dẫn file trên server
2. FileData: Lưu file vào database dưới dạng mảng byte

Tạo mới class tên là FileModel.cs trong thư mục Model chứa các thuộc tính chung

public abstract class FileModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string FileType { get; set; }
    public string Extension { get; set; }
    public string Description { get; set; }
    public string UploadedBy { get; set; }
    public DateTime? CreatedOn { get; set; }
}

Tiếp theo ta sẽ tạo 2 models cho việc lưu file vào cơ sở dữ liệu và lưu vào ổ đĩa trên server, 2 models này kế thừa lại các thuộc tính của FileModel

Models/FileOnFileSystem.cs

public class FileOnFileSystemModel : FileModel
{
    public string FilePath { get; set; }
}

Models/FileOnDatabaseModel.cs

public class FileOnDatabaseModel : FileModel
{
    public byte[] Data { get; set; }
}

Tiếp theo cần xây dựng cơ sở dữ liệu để lưu file

Setting Up Entity Framework Core

Đầu tiên cần Install 1 số packages

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Microsoft.EntityFrameworkCore.Tools
Install-Package Microsoft.EntityFrameworkCore.SqlServer

Add ConnectionStrings vào file Appsetting.json

"ConnectionStrings": {
  "DefaultConnection": ""
}

Cấu hình file Startup.cs, hàm ConfigurationService

services.AddDbContext(options =>
    options.UseSqlServer(
    Configuration.GetConnectionString("DefaultConnection"),
    b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)));

Tự động sinh database từ model
 

add-migration Initial
update-database

Sau khi chạy, kiểm tra database xem kết quả

IFormFile Trong C#

IFormFile là 1 Interface của ASP.NET Core, IFormFile có một số thuộc tính như Name, FileName, ContentType ... và một số phuong thức Copy data vào memory Stream

Ý tưởng là: Từ thẻ Form HTML, sau khi nhấn submitt, sẽ gửi đi 1 list file, list file đó sẽ được gán vào mảng IFormFile, sau đó thực hiện các thao tác để lưu file vào database, ổ đĩa trên server

Đầu tiên tạo controller Controllers/FileController  sau đó Add View tương ứng

Setting Up The View And ViewModel

ViewModel là gì?

View Model hiếu đơn giản là class, trong class đấy sẽ chứa các thông tin mà ta muốn hiển thị lên màn hình, trong project này, ta muốn hiển thị 2 models, 1 cái là thông tin về FIleUpload lên database, 1 cái là FileUpload lên ổ đĩa.

Vì 1 Controller/View chỉ có thể có duy nhất 1 ViewModel, nhưng ta lại muốn 2 Model cùng được lên cơ, để làm được điều đó thì ta sẽ tạo 1 class, class này chứa List FileOnFileSystemModel List FileOnDatabaseModel  có tên là FileUploadViewModel.cs trong thư mục Model như sau:

public class FileUploadViewModel
{
    public List FilesOnFileSystem { get; set; }
    public List FilesOnDatabase { get; set; }
}

Sau đó ta sửa View Index vừa tạo bên trên Views/File/Index.cshtml:

@model FileUploadViewModel
@{
    ViewData["Title"] = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

Start Uploading Files Here


@if (ViewBag.Message != null) {
@ViewBag.Message
}

@model FileUploadViewModel: Dòng này định nghĩa rằng cái View này sẽ ứng với Model FileUploadViewModel

Tiếp theo ta hiển thị danh sách file đã được upload

File Upload In ASP.NET Core MVC To File System

sửa file Index.cshtml, thêm đoạn code sau xuống dưới cùng


Files on File System

@if (Model.FilesOnFileSystem.Count == 0) { No Records Found } else { List of Files on File System @foreach (var file in Model.FilesOnFileSystem) { }
# Name Description File Type Created On Actions
@file.Id @file.Name @file.Description @file.FileType @file.CreatedOn Download Delete
}

File Controller

Trong FileController, hãy thêm ApplicationDbContext vào để có thể làm việc với database

private readonly ApplicationDbContext context;
public FileController(ApplicationDbContext context)
{
    this.context = context;
}

Đầu tiên, tạo phương thức LoadAllFiles, như cái tên, phương thức này để lấy hết file từ database ra và hiển thị lên View, 

private async Task LoadAllFiles()
{
    var viewModel = new FileUploadViewModel();
    viewModel.FilesOnDatabase = await context.FilesOnDatabase.ToListAsync();
    viewModel.FilesOnFileSystem = await context.FilesOnFileSystem.ToListAsync();
    return viewModel;
}

Tiếp theo, sửa lại phương thức Index()

public async Task Index()
{
    var fileuploadViewModel = await LoadAllFiles();
    ViewBag.Message = TempData["Message"];
    return View(fileuploadViewModel);
}

Tiếp theo ta tạo phương thức để UploadFile vào ổ đĩa, sau khi nhấn nút UploadFileToSystem, sẽ nhày vào phương thức này.

[HttpPost]
public async Task UploadToFileSystem(List files, string description)
{
    foreach(var file in files)
    {
        var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\Files\\");
        bool basePathExists = System.IO.Directory.Exists(basePath);
        if (!basePathExists) Directory.CreateDirectory(basePath);
        var fileName = Path.GetFileNameWithoutExtension(file.FileName);
        var filePath = Path.Combine(basePath, file.FileName);
        var extension = Path.GetExtension(file.FileName);
        if (!System.IO.File.Exists(filePath))
        {
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }
            var fileModel = new FileOnFileSystemModel
            {
                CreatedOn = DateTime.UtcNow,
                FileType = file.ContentType,
                Extension = extension,
                Name = fileName,
                Description = description,
                FilePath = filePath
            };
            context.FilesOnFileSystem.Add(fileModel);
            context.SaveChanges();
        }
    }
    TempData["Message"] = "File successfully uploaded to File System.";
    return RedirectToAction("Index");
}

Đầu vào sẽ là 1 danh sách file, chi tiết mô tả về các file đó

var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\Files\\");

Dòng này là  để trỏ tới đường dẫn lưu file đó, 2 dòng tiếp theo nếu đường dẫn chưa tồn tại, sẽ tạo ra đường dẫn đó

Dòng tiếp theo, lấy tên File không vào gồm phần mở rộng 

var fileName = Path.GetFileNameWithoutExtension(file.FileName);

Vi dụ File là Avatar.png, phần mở rộng ở đây là .png

Dòng tiếp theo

var filePath = Path.Combine(basePath, file.FileName);

kết hợp tên file FilePath
Ví dụ: fileName là Avatar
Đường dẫn là: E:/Projects/YourProject/Files
Dòng này sẽ cho kết quả filePath = E:/Projects/YourProject/Files/Avatar

Dòng tiếp theo sẽ lấy phần mở rộng của file .png, .jpg,...

var extension = Path.GetExtension(file.FileName);

 

 


Tags: C#
Web hosting by Somee.com