Hoşgeldin Misafir

Kod ASP.Net MVC Core Sürükle&Bırak Dosya Yükleme

akinbndr

21 Ocak 2018
5 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Merhaba Arkadaşlar,

Hack konusunda bilgi sahibi olmamama rağmen, bildiğim konular üzerinde bir yazı dizisine başlayayım dedim. MVC Core üzerine sıfırdan bir yazı dizisine başlayacağım önümüzdeki içerisinde ama yeni aldığım projede yazdığım işinize yarayabilecek olan bazı kodları sizinle şimdiden paylaşayım dedim.

Bu konuda DropzoneJS kullanarak MVC Core uygulamasında sürükle bırak dosya yüklemeyi nasıl gerçekleştirebileceğimizi göstereceğim. Bunun için öncelikle Entity Framework ile yazılmış bazı Model sınıflarını inceleyelim. İlan ekleme yapabileceğimiz bir controller düşünelim. Yüklenecek resmi veritabanına yüklemektense, serverda bi dosyaya yükleyip, resmin dosya konumunu veritabanına kaydetmek daha mantıklı olduğu için bu örnekte de öyle yapacağım.

Kod:
    public class Ilan
    {
        [Key]
        public int IlanID { get; set; }
        [Display(Name = "İlan Başlığı")]
        public string IlanBasligi { get; set; }
        public DateTime IlanTarihi { get; set; }

        public virtual ICollection<Resim> Resimler { get; set; }
    }
Kod:
    public class Resim
    {
        [Key]
        public int ResimID { get; set; }
        public string Path { get; set; }
        public int? IlanID { get; set; }
        public virtual Ilan Ilan { get; set; }
    }

Entity Framework Core ile database oluşturma ve tablo ilişkilerini yazı dizimde daha sonra paylaşacağım.

şimdi controllerda yüklemenin nasıl gerçekleştiğine bakalım.

Kod:
        [HttpPost]
        public async Task<IActionResult> PhotoUpload(int IlanId)
        {
            var files = HttpContext.Request.Form.Files;
            //Yüklenecek resim varsa, ilan için dosya oluştur
            if (files.Count > 0)
            {
                var Ilan = await _context.Ilan.SingleOrDefaultAsync(m => m.IlanID == IlanId);
                string ImagesRoot = Path.Combine(_hostingenv.WebRootPath,"IlanResimler", Ilan.IlanID.ToString());
                if (!Directory.Exists(ImagesRoot))
                {
                    Directory.CreateDirectory(ImagesRoot);
                }
                try
                {
                    foreach (var file in files)
                    {
                        if (file.Length > 0)
                        {
                            var FilePath = Path.Combine(ImagesRoot, file.FileName);
                            using (var fileStream = new FileStream(FilePath, FileMode.Create))
                            {
                                await file.CopyToAsync(fileStream);
                            }
                            var Photo = new Resim
                            {
                                IlanID = IlanId,
                                Path = FilePath
                            };
                            _context.Resim.Add(Photo);
                            _context.SaveChanges();
                        }
                    }
                }
                catch (Exception)
                {
//Hata olursa istediğinizi yapın, size kalmış.
                    throw;
                }
            }
            return RedirectToAction(nameof(Index));
        }

Server'a dosya yüklemenin birçok yöntemi var. MVC 5 de "HttpPostedFileBase" ile yükleme yapılırken, MVC Core da "IFormFile" kullanılmaya başlandı. Fakat yüklemeyi Jquery ile yaparken IFormFile kullanamadığımdan, HttpContext.Request.Form.Files ile View'den (kullanıcıdan) gelen dosyaları yakaladım. Önemli olan ayrıntı burası. Daha sonrası zaten veritabanına kayıt işlemleri..

View'da ise böyle DropzoneJS i böyle kullandım:
Kod:
<link href="~/lib/dropzone/dist/dropzone.css" rel="stylesheet" />

<div class="row justify-content-md-center">
    <div class="col-md-10 col-lg-8">
        <form asp-controller="Ilan" asp-action="PhotoUpload" asp-antiforgery="false"
              class="dropzone" id="uploader" enctype="multipart/form-data">
            <input type="hidden" asp-for="IlanID" />
            <div class="fallback">
                <input name="file" type="file" multiple />
                <input type="submit" asp-controller="Ilan" asp-action="PhotoUpload" class="btn btn-default" />
            </div>
        </form>
        <a asp-controller="Ilan" asp-action="Editor" [email protected] class="btn btn-primary">İlerle</a>
    </div>
</div>

<script src="~/lib/dropzone/dist/dropzone.js"></script>
<script>
    $(document).ready(function () {
        Dropzone.options.uploader = {
            paramName: "file",
            maxFilesize: 20
        };
    });
</script>

"fallback" div'i, sürükle bırak özelliğini desteklemeyen web tarayıcıları için alternatif bir çözüm sağlıyor. Bootstrap 4 ün alfa sürümünü kullandığım için justify-content-md-center yazıyor. Daha önce karşılaşmadıysanız diye belirtmek istedim. Script kısmında önemli olan "paramName" in Controllerın parametresiyle aynı ada sahip olması. Aksi taktirde controller tetiklenip kayıt yapmaz. Kullanmadım ama internetten okuduğum makalelerde parallelUploads ve uploadMultiple gibi güçlü ayarları varmış. http://www.dropzonejs.com/ sitesinden dökümantasyona bakarak, kendiniz ekstra ayar yapabilirsiniz. MVC Core uygulamanıza Dropzone u eklemek için Bower kullanabilirsiniz, veya kendiniz sitesinden indirip uygulama dosyalarınız arasına atabilirsiniz. 

Çalıştıramazsanız veya sorularınız olursa, her zaman yardımcı olmaya çalışırım. İyi kodlamalar dilerim.