Upload File

Back End

Untuk mengupload file ke dalam website asp.net mvc, kita memerlukan tipe IFormFile, contoh jika ingin menambahkan avatar pada User, maka pada file Areas/Identity/Account/Manage/Index.cshtml.cs ubahlah definisi dari class InputModel menjadi:

public class InputModel
{
    [Phone]
    [Display(Name = "Phone number")]
    public string PhoneNumber { get; set; }

    public IFormFile AvatarFile { get; set; }
}

Ataupun dalam action method juga bisa, sebagai parameter:

public IActionResult UploadFile(IFormFile file)
{
    // Lakukan sesuatu dengan filenya
    return Ok();
}

Sebelum mengupload, buatlah sebuah directory untuk menyimpan gambar-gambar kita, masih dengan contoh avatar, berarti misal nama directory nya "Avatars":

var avatarDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Avatars");

Disini kita melakukan tiga hal, yaitu yang pertama adalah mengambil directory tempat server kita berada menggunakan Directory.GetCurrentDirectory() lalu menggabungkannya dengan directory Avatars menggunakan Path.Combine() dan menyimpannya kedalam variabel avatarDirectory, sehingga variabel tersebut akan berisi directory lengkap server kita+"Avatars"

Setelah mendapatkan directory yang ingin kita jadikan sebagai target, kita masih perlu membuatnya jika belum ada:

Directory.CreateDirectory(avatarDirectory);

Method tersebut akan membuat directory jika belum ada, dan tidak akan melakukan apa apa jika sudah ada, jadi kita tidak perlu khawatir akan menimpa directory.

Setelah directory dibuat, kita perlu memastikan apakah ekstensi dari file yang diupload sesuai dengan kriteria yang kita inginkan. Langkah pertama yang perlu dilakukan adalah mengambil ekstensinya terlebih dahulu:

var extension = Path.GetExtension(Input.AvatarFile?.FileName)?.ToLowerInvariant();

Path.GetExtension akan mengembalikan ekstensi dari suatu filename/path jadi jika kita masukkan "gambar.jpg" yang dikembalikan adalah ".jpg", jika kita memasukkan "avatar.PNG" yang dikembalikan adalah ".PNG" dst.

Setelah Path.GetExtension dieksekusi, selanjutnya hasilnya akan dikonversi menjadi lower case (huruf kecil) menggunakan string.ToLowerInvariant()

Nah setelah mendapatkan ekstensinya, kita akan mengecek dengan tipe-tipe yang ditentukan dengan membuat array:

var permittedType = new string[] { ".png", ".jpg" };

Kita akan gunakan array tersebut untuk mengeceknya:

if (string.IsNullOrEmpty(extension) || !permittedType.Contains(extension))
{
    StatusMessage = "Unsupported file type";
    return RedirectToPage();
}

Contoh tersebut ada di file Areas/Identity/Account/Manage/Index.cshtml.cs yang memiliki StatusMessage dan RedirectToPage(), jika menggunakan controller biasa kemungkinan akan berbeda, cek dokumentasi resmi untuk informasi lebih lanjut.

Jika validasi sudah dilakukan, sekarang saatnya kita mulai mengupload file ke server,

  • Pertama, buat nama filenya, di contoh avatar ini kita menggunakan id dari user agar menghindari nama file yang sama (id dari user pasti unique), jadi nama filenya adalah id user+ekstensi.

  • Setelah mendapatkan nama file, kita gabungkan ke directory avatar kita.

  • Lalu menggunakan FileStream, kita akan menuliskan file ke server menggunakan FileMode.Create yang akan membuat dan menimpa jika sudah ada.

  • Setelah kita memiliki FileStream kita copy isi file dari model menggunakan method IFormFile.CopyTo atau IFormFile.CopyToAsync dengan memasukkan FileStream yang baru saja kita buat sebagai argument

  • Setelah kita menuliskan file ke server, kita simpan perubahan avatar ke database.

var fileName = $"{user.Id}{extension}";
var avatarFile = Path.Combine(avatarDirectory, fileName);
using var stream = new FileStream(avatarFile, FileMode.Create);
await Input.AvatarFile.CopyToAsync(stream);
user.Avatar = fileName;
await _userManager.UpdateAsync(user);

Jika langkah-langkah tersebut berhasil, di server akan ada folder baru, yaitu "Avatars" yang berisi gambar

Front End

Pada front end, kita dapat menggunakan input type file, atau jika menggunakan model, tinggal dimasukkan saja seperti input-input lain.

Contoh berikut menggunakan file Areas/Identity/Account/Manage/Index.cshtml yang di sudah di generate otomatis:

<div class="form-group">
    <label asp-for="Input.AvatarFile"></label>
    <input asp-for="Input.AvatarFile" accept=".png, .jpg" class="form-control" />
    <span asp-validation-for="Input.AvatarFile" class="text-danger"></span>
</div>

Input.AvatarFile diambil dari contoh file yang sudah kita ubah di bagian sebelumnya. lalu atribut accept akan memfilter file mana saja yang boleh diupload.

Tapi menambahkan input saja tidak cukup, kita perlu mengubah form kita agar meng encode data yang akan dikirim menggunakan "multipart/form-data" yang memungkinkan kita untuk mengirim file:

<form id="profile-form" method="post" enctype="multipart/form-data">

Cobalah jalankan dan upload file, jika mengikuti contoh ini, file kalian akan berada di DirectoryProjectKalian/Avatars

Menampilkan gambar dari server

Untuk menampilkan gambar kita perlu membuat action nya terlebih dahulu.

Masih menggunakan contoh sebelumnya, kita akan membuat controller ProfileController yang akan menangani masalh profil.

Pada controller tersebut, buatlah action method baru bernama Avatar dengan parameter fileName:

public async Task<IActionResult> Avatar(string fileName)
{
    var avatarFile = Path.Combine(Directory.GetCurrentDirectory(), "Avatars", fileName);
    new FileExtensionContentTypeProvider().TryGetContentType(avatarFile, out var contentType);
    var fileBytes = await System.IO.File.ReadAllBytesAsync(avatarFile);
    return File(fileBytes, contentType ?? "application/octet-stream");
}

Di method tersebut, langkah pertama yang akan dilakukan adalah mengambil directory lengkap dimana file tersebut berada dalam server menggunakan Path.Combine. Lalu mencari "meta data" yang tepat menggunakan FileExtensionContentTypeProvider.TryGetContentType, hasilnya akan disimpan dalam contentType. Lalu terakhir file akan dikirmkan menggunakan method File dengan membaca seluruh byte file avatar dan mengirimkan contentType bersamanya.

Sekarang, fila dapat diakses melalui alamat https://{alamat_web}/Profile/Avatar/{nama_file} cobalah buka, jika berhasil file nya akan ditampilkan (jika gambar) dan akan di download jika selain gambar.

Setelah memiliki sistem untuk mendapatkan file, kita dapat mengirimkannya ke manapun. Misal pada tag img:

<img src="https://{alamat_web}/Profile/Avatar/{nama_file}" class="w-100" alt="">

Last updated