Sayfalar

13 Şubat 2013 Çarşamba

ASP.NET MVC AJAX FILE UPLOAD (JQUERY AJAX FORM PLUGIN)

Öncelikle hızlıca kodları paylaşayım, gerekli açıklamaları daha sonra yaparım.

Gerekli JQuery kütüphaneleri
JQuery ve JQueryAjaxFormPlugin

_Layout.cshtml sayfamızda JQuery kütüphanalerini tanımlıyoruz.

_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title - Yönetim Paneli</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <meta name="viewport" content="width=device-width" />
    <script src="~/Scripts/jquery.min.js"></script>
    <script src="~/Scripts/jquery.form.js"></script>
</head>
<body>
    <div>@RenderBody()</div>
    <footer id="footer" class="clear-fix">
        <div class="float-right">
            <p class="copyright">&copy; @DateTime.Now.Year - Web ASYA</p>
        </div>
    </footer>
</body>
</html>

AuthorViewModel.cs
public class AuthorViewModel
{
    public int Id { get; set; }

    [Required(ErrorMessage = "{0} alanı boş bırakılmamalıdır!")]
    [Display(Name = "Yazar Adı")]
    public string Name { get; set; }

    [Display(Name = "Kısa Özgeçmiş")]
    public string Description { get; set; }

    [Display(Name = "E-Posta")]
    public string Email { get; set; }

    [Display(Name = "Doğum Tarihi")]
    public Nullable<DateTime> Birthday { get; set; }

    [Display(Name = "Yazar Resim")]
    public string OrginalImageUrl { get; set; }

    public string SmallImageUrl { get; set; }

    public HttpPostedFileBase file { get; set; }
}

FileUploadController.cs
[HttpPost]
public ActionResult FileUpload(AuthorViewModel viewModel)
{
    ...
    // dosya otomatik olarak viewModel içerisindeki 
    // file değişkenine bağlanmıştır.
    var file = viewModel.file;
    ...
}

FileUpload.cshtml
@model AuthorViewModel
<script>
    $(function () {
        $('#form_author').ajaxForm({
            beforeSubmit: ShowRequest,
            success: SubmitSuccesful,
            error: AjaxError
        });
    });

    // form gönderilmeden önce çalışacak olan fonksiyon
    function ShowRequest(formData, jqForm, options) {
        $(".loading_container img").show();
    }

    // form gönderirken hata oluşursa bu fonksiyon çalışır
    function AjaxError() {
        alert("An AJAX error occured.");
    }

    // form gönderildikten sonra çalışacak olan fonksiyon
    function SubmitSuccesful(result, statusText) {
        // result controllerdan geri dönen veri
        // statusText, ajax başarılı ise true değilse false
    }
</script>
<div class="right_inner_container">
    <table>
        <tr>
            <td>
                @using (Html.BeginForm("FileUpload", "FileUpload", FormMethod.Post, new { id = "form_author" }))
                {
                    <div class="editor-label">
                        <input type="file" name="file" id="file" />
                    </div>
                    <div class="editor-label">
                        @Html.LabelFor(model => model.Name)
                    </div>
                    <div class="editor-field">
                        @Html.TextBoxFor(model => model.Name, new { @class = "custom_textbox" })
                    </div>
                    <div class="editor-field">
                        @Html.ValidationMessageFor(model => model.Name)
                    </div>

                    <div class="editor-label">
                        @Html.LabelFor(model => model.Description)
                    </div>
                    <div class="editor-field">
                        @Html.TextAreaFor(model => model.Description, new { @class = "custom_textarea" })
                    </div>
                    <div class="editor-field">
                        @Html.ValidationMessageFor(model => model.Description)
                    </div>

                    <div class="editor-label">
                        @Html.LabelFor(model => model.Email)
                    </div>
                    <div class="editor-field">
                        @Html.TextBoxFor(model => model.Email, new { @class = "custom_textbox" })
                    </div>
                    <div class="editor-field">
                        @Html.ValidationMessageFor(model => model.Email)
                    </div>

                    <div class="editor-label">
                        @Html.LabelFor(model => model.Birthday)
                    </div>
                    <div class="editor-field">
                        @Html.TextBoxFor(model => model.Birthday, new { @class = "custom_textbox easyui-datebox" })
                    </div>
                    <div class="editor-field">
                        @Html.ValidationMessageFor(model => model.Birthday)
                    </div>

                    <div class="submit-field">
                        <input type="submit" value="Ekle" class="button_gray" />
                    </div>
                }
            </td>
        </tr>
    </table>
</div>

Neler Yaptık?
  1. Standart JQuery ve JQueryAjaxForm kütüphanelerini indirdik.
  2. Layout ve ya content sayfası içerisinde scriptleri tanımladık.
  3. Standart JQuery Ajax form post gibi FileUploadView içerisinde tanımladığımız modeli ajax ile controller metoda gönderdik.
  4. Normalde ekstra bir kütüphane kullanmadan modeli ajax ile gönderebiliyoruz fakat dosya gönderemiyoruz. AjaxFormPost kütüphanesi bu işi yapıyor.
ÖNEMLİ: Aslında kodlar üzerinde yeterince açıklama yapmaya çalıştım. Ama tekrar etmekte fayda var. Model içerisinde tanımladığımız HttpPostedFileBase tipindeki değişken için View sayfasında hiç bir model bağlama işlemi (ModelBinding) yapmadık, böyle yaptığımız halde, seçilen dosya model içerisindeki File değişkenine otomatik bağlandı. Peki bu nasıl oldu? MVC bunu isimlerden anlıyor. Yani modeldeki değişken ismi File ise View sayfasındaki file elementininde id si File olmalı. 

12 yorum:

  1. Resim yüklemesi için bilgisayara gözat kısmından resim seçilip servera bir dizine upload edilip veritabanına dizin adresinin kaydı (ImageUrl)nasıl yapılır?

    YanıtlaSil
    Yanıtlar
    1. https://github.com/alirizaadiyahsi/HaberPortal

      Bu adreste, örnek bir mvc uygulaması var. İndirip inceleyebilirsiniz. ~/Areas/Admin içerisinde file upload yapılan kısımlar var.

      Sil
  2. İyi de hangisi controller hangisi view hangisi class belirtmemişsin

    YanıtlaSil
    Yanıtlar
    1. kodların üzerinde yazıyor. anlamadıgınız yer neresi ise soylerseniz yardımcı olurum...

      Sil
  3. controller içerisine başka bir kod yazılmasına gerek varmı

    YanıtlaSil
  4. Merhaba , sonlarda yer alan div class = right_inner_container ile başlayan ve devam eden satır nereye yazılması gerekli

    YanıtlaSil
    Yanıtlar
    1. Kod satırlarının üstlerinde ait oldukları dosya isimleri yazıyor. scriptler ve sizin söylediğiniz kısım FileUpload.cshtml içerisinde olacak...

      Sil
  5. Çok faydalı bir yazı olmuş öncelikle teşekkür ederim ama bir eleştiride bulunmak istiyorum :)
    Modeli bu kadar uzun tutmanıza gerek yoktu.Sadece file propertysini tutsanız yeterliydi diye düşünüyorum.Konuyla alakalı daha sade ve okunaklı olurdu .

    YanıtlaSil
  6. Kardeş mümkünse proje dosyalarını upload edebilirmisiniz. Bir sürü hata oluşuyor.Örneğin ben loading_container img bu clasın nerede olduğunu bulamadım. Bir kaç sorun daha var. Neyse uzatmayayım. Proje dosyalarını upload edebilirseniz daha az sorun yaşarız.
    Yazı için teşekkürler yinede.

    YanıtlaSil
  7. Teşekkürler Adıyahşi :) Burada bakarak tek seferde çözdüm sorunu

    YanıtlaSil
  8. Şefim kafayı yicem. Modele HttppostedFiles Değişkenleri oluşturuyorum lakin upload controllere göndermiyor. Diğer alanlar gidiyor Dosya göndermiyor

    YanıtlaSil