Visual Studio ile yeni bir boş proje oluşturalım.
Proje Oluşturma Adım 1
Proje Oluşturma Adım 2
Proje Oluşturma Adım 3
Proje Görünümü
Basit bir web projesi oluşturduk. Şimdi ise sırasıyla wwwroot, Views ve Controllers klasörlerini oluşturup altyapı oluşturmaya devam edelim.
İlgili Klasörler Oluşturuldu
Şimdi ise AnasayfaController adında bir Controller oluşturalım
AnasayfaController
Anasayfa View
Controller ve View Görünümü
Controller ve View yapısı oluşturuldu. Şimdi kodlarımızı yazmaya başlayalım. Kod kısmında öncelik olarak basit bir form tasarımı yapalım.
Index.cshtml Betikleri
<div class="kapsul"> <form method="post" enctype="multipart/form-data"> <h1>AspNet Core Mvc Ajax File Upload</h1> <div class="satir"> <div class="input-kapsul"> <label class="baslik">Dosya</label> <input type="file" name="dosya" class="input js-input-dosya" /> </div> </div> <div class="satir"> <div class="input-kapsul"> <label class="baslik">Dosya Adı</label> <input type="text" name="dosya_adi" class="input js-input-dosya-adi" placeholder="Dosya adı belirtiniz.." /> </div> </div> </form> <div class="satir"> <div class="js-dosya-yukle-hedef"></div> </div> </div>
Html iskeletini oluşturduk. Bu iskeleti CSS ile şekillendirelim.
CSS Betikleri
*{margin:0;padding:0;font-family:inherit;} body{font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;background-color:#f5f5f5;font-size:12px;line-height:20px;} h1{font-size:18px;margin-bottom:10px;text-align:center;} .kapsul{width:600px;position:relative;background:#fff;margin:10px auto;padding:10px;} .satir{margin-bottom:10px;} .input-kapsul{font-size:13px;height:auto;outline:none;box-shadow:inset 1px 2px 0 rgba(0, 0, 0, 0.06);border:1px solid #D9D9D9;background-color:#fff;padding:0px 10px;} .input-kapsul .input{display:block;width:100%;height:34px;border:none;line-height:1.42857143;color:#555;background-color:transparent;outline:none;} .input-kapsul .baslik{display:block;font-weight:bold;color:#969696;font-size:10px;cursor:text;transition:all .25s ease;padding:5px 0px 0px 0px;} .dosya-kapsul{padding:5px;min-height:1px;text-align:center;margin:0 0 10px 0px;border:1px solid #eee;background:#fff;position:relative;display:block;width:200px;} .dosya-kapsul:hover{border-color:#bbb;} .dosya-kapsul .dosya-adi{display:block;margin-bottom:5px;} .dosya-kapsul img{max-width:100%;display:block;margin:5px auto;}
Çalışmamızı biraz ilerlettik. Çalışmaya ait görünümü paylaşalım.
Çalışma Görünümü
CSS ile güzelleştirdiğimiz formu JavaScript ile aksiyon kazandıralım. Nedir bu aksiyon; Tıklayınca dosya seçtirecek. Seçtiği dosyayı otomatik olarak bizim belirlediğimiz adrese formdaki tüm bilgilerle gönderimini sağlayacak.
JavaScript Betikleri
var objInputDosya = document.getElementsByClassName('js-input-dosya')[0]; objInputDosya.addEventListener("change", function () { let strDosya = objInputDosya.files[0]; let strDosya_Adi = document.getElementsByClassName("js-input-dosya-adi")[0].value; let objDosya_Yukle_Hedef = document.getElementsByClassName("js-dosya-yukle-hedef")[0]; objDosya_Yukle_Hedef.innerHTML = "Yükleniyor.."; let fdVeriler = new FormData(); fdVeriler.append("strDosya_Adi", strDosya_Adi); fdVeriler.append("fuDosya", strDosya); const optAyarlar = { method: "POST", mode: "no-cors", body: fdVeriler, contentType: false, processData: false } fetch('/ajax/dosya-yukle', optAyarlar) .then(function(response) { return response.text() }) .then((sonuc) => { objDosya_Yukle_Hedef.innerHTML = sonuc; }).catch(hata => { alert("Bir hata oluştu! Hata detayları: " + hata); }); });
JavaScript taraflı kodlarımızı hazırladık. Burada işleyiş şu şekildedir;
- File dosyası change (değiştiğinde) olduğunda olayı tetikletiyoruz.
- Tetiklendiğinde formdaki verileri alıyoruz. İlgili dosyayı, dosya adını içeren form verileri.
- Ajax ile '/ajax/dosya-yukle' adlı adrese POST işlemi ve gerekli ayarlarla gönderiliyor.
- POST işlemi başarılı olduğunda class="js-dosya-yukle-hedef" adlı div içerisine sonucu yazdırıyoruz.
- Ajax işlemi başarısız ise ekrana uyarı verdiriyoruz.
JavaScript/CSS taraflı hazırlıklar tamamlandı. Bu adımda POST edilen form verilerini karşılayacak olan ajaxController'ı hazırlayalım.
ajaxController Betikleri
public class ajaxController : Controller { private readonly IWebHostEnvironment _iwheWebHostEnvironment; public ajaxController(IWebHostEnvironment iwheWebHostEnvironment) { _iwheWebHostEnvironment = iwheWebHostEnvironment; } public IActionResult Index() { return View(); } public string fnSayi_Uret() { string strSonuc = DateTime.Now.ToString("yyyyMMdd hh:mm:ss").Replace(" ", "-").Replace(":", string.Empty); return strSonuc; } [Route("ajax/dosya-yukle")] [HttpPost] public string dosya_yukle(string strDosya_Adi, IFormFile fuDosya) { string strKlasor = "wwwroot/dosyalar/"; string strKlasor_Relative = "/wwwroot/dosyalar/"; string strSonuc = string.Empty; bool blnDosya_Yukle = false; bool blnResim = false; string strDosya_Tipi = fuDosya.ContentType; switch(strDosya_Tipi) { case "application/vnd.ms-word": blnDosya_Yukle = true; break; case "application/pdf": blnDosya_Yukle = true; break; case "application/octet-stream": blnDosya_Yukle = true; break; case "application/vnd.ms-excel": blnDosya_Yukle = true; break; case "application/vnd.openxmlformats-officedocument.presentationml.presentation": blnDosya_Yukle = true; break; case "image/jpg": blnDosya_Yukle = true; blnResim = true; break; case "image/jpeg": blnDosya_Yukle = true; blnResim = true; break; case "image/png": blnDosya_Yukle = true; blnResim = true; break; case "image/gif": blnDosya_Yukle = true; blnResim = true; break; case "video/mp4": blnDosya_Yukle = true; break; default: break; } if (blnDosya_Yukle) { string strContentRootPath = _iwheWebHostEnvironment.ContentRootPath; string strDosya_Patika = Path.Combine(strContentRootPath, strKlasor); if (!Directory.Exists(strDosya_Patika)) { Directory.CreateDirectory(strDosya_Patika); } if (string.IsNullOrEmpty(strDosya_Adi)) { strDosya_Adi = Path.GetFileNameWithoutExtension(fuDosya.FileName); } string strDosya_Uzantisi = Path.GetExtension(fuDosya.FileName); string strSayi = fnSayi_Uret(); strDosya_Adi = strDosya_Adi + "-" + strSayi + strDosya_Uzantisi; using (FileStream fsDosya_Akis = new FileStream(Path.Combine(strDosya_Patika, strDosya_Adi), FileMode.Create)) { fuDosya.CopyTo(fsDosya_Akis); } string strDosya_Adresi_Relative = strKlasor_Relative + strDosya_Adi; strSonuc = $"<div class='dosya-kapsul'>"; if (blnResim) { strSonuc += $"<span class='dosya-adi'>{strDosya_Adi}</span><img class='resim' src='{strDosya_Adresi_Relative}' alt='{strDosya_Adi}' />"; } else { strSonuc += $"<a href='{strDosya_Adresi_Relative}' target='_blank'>{strDosya_Adi}</a>"; } strSonuc += $"</div>"; } return strSonuc; } }
Form verilerini karşılayan ajaxController'ı hazırladık. Şimdi ise Startup.cs içerisinde birkaç ayarlama yapalım. Çünkü uygulama yaşam döngüsünde "MVC controller'ı çalışsın", "URL Route işlemi yapılsın" ve "wwwroot adlı klasörü dışa açılsın" şeklinde gereksinimleri hazırlayalım.
Startup.cs Betikleri
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")), RequestPath = "/wwwroot" }); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Anasayfa}/{action=Index}" ); }); }
Çalışmamız bitti. Uygulamaya ait proje dosyalarını Github üzerinden indirebilirsiniz. Github linki