Asp.net MVC FileResult Dosyasını JQuery Ajax ile Yakalamak

1 Eyl

Asp.net mvc projelerinde dosya sonuçlarını kullanıcıya dönmek için action sonucunda File() metodu ile dönüş yapılabilmektedir.

Örneğin bir PDF için.

[HttpPos]
public FileContentResult Test(TestViewModel vm)
{
    var stream = new MemoryStream();
    //... add content to the stream.

    return File(stream.GetBuffer(), "application/pdf", "test.pdf");
}

Excel için;

[HttpPost]
public FileContentResult Test(TestViewModel vm)
{
    var stream = new MemoryStream();
    //... add content to the stream.

    return File(stream.GetBuffer(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "File.xlsx");
}

Bu oluşturulan dosyaya javascript tarafından jquery ile request gönderilirken dikkat edilmesi gereken bir husus, jquery’nin dosyayı bozmasıdır. Benzer bir durum burada yaşanmıştır. Dosya indiriliyor fakat bozuk olduğu için excel tarafından açılamıyor.

Bunu düzeltmek için xhrFields alanında responseType olarak arraybufffer değeri verilmelidir.

$.ajax({
    url: '/server/url',
    type: 'POST',
    contentType: "application/json; charset=utf-8",
    xhrFields : {
	   responseType : 'arraybuffer'
    },
    data: JSON.stringify(jsonData),   
    success: function (data) {
        var blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
        var downloadUrl = URL.createObjectURL(blob);
        var a = document.createElement("a");
        a.href = downloadUrl;
        a.download = "data.xls";
        a.click();
    },
});

Asp.net MVC web site oluşturma platformu olması dolayısı ile günümüzde çok sık kullanılmasa bile hala günümüzde yaygın olarak kullanılmaktadır. Dosya indirme konusunda internette epeyce aranmış ve çok fazla çözüm gösterilememiş bir konuya açılık getirmek istedim.

JQuery event.stopPropagation() ve event.preventDefault() metodları

23 Ara

JQuery ile event yakalama işlemleri sırasında iç içe geçmiş HTML elementleri sırasında istemeden bazı karışıklıklara neden olabiliriz. Bu karışıklıklardan bir tanesi, bir elementteki event tetiklendiğinde onun üst elementlerinde de olayın tetiklenmesidir.

event.stopPropagation()

Örneğin bir unorderedlist (<ul>) ile çalışırken listedeki bir eleman(<li>) tıklandığında, hemen (<ul>) elementinde de “click” event tetiklenecektir. Çünkü bu ili element iç içe barındırılmaktadır. Eğer (<li>) elementine tıklandığında (<ul>) elementinde bir “click” event gerçekleşmesinin istenmediği durumda event.stopPropagation() metodu kullanılmaktadır.


$("li").click(function(event){
   event.stopPropagation();
   alert("The li element was clicked.");
});

 

event.preventDefault()

Bir diğer durum ise HTML elementlerinin mevcut eylemlerini engelleme isteğidir. Örneğin bir link tıklandığında doğrudan linkin gösterdiği adrese yönlendirme yapılır. Ancak link tıklandığında bu eylemin engellenmesi gerekiyor ise event.preventDefault(); metodu kullanılabilir.


$("a").click(function(event){
   event.preventDefault();
});

Bu durumda link tıklansa da adrese yönlendirme yapılmaz.

Javascript ve HTML Dom element etkileşimleri

8 Ara

Javacsript kodu ile HTML Dom elementler arasındaki etkileşimleri genelde elementin ID değeri üzerinden sağlarız. Javascript kodu ile document.getElementById(“elementId”) şeklinde ID aracılığıyla elementin seçilebilmesi mümkündür. Bu aşamadan sonra ise element üzerindeki bir değerin değiştirilmesi veya bir olayın(event) tetiklenmesi gibi işlemeri yapmak daha kolay hale gelmektedir.

HTML elementleri üzerinde tanımlı mevcut nitelikler(attributes), javascript tarafından elemente erişmemizi sağlarlar. Mevcut elementlerin kullanılabildiği gibi kendi tanımlayacağımız özel elementler üzerinden de bağlantı kurmamız mümkündür. Günümüzde kullanılan birçok Javascript kütüphanesi kendi tanımladığı nitelikler üzerinden işlemlerini yürütmektedir. Örneğin AngularJS ile çelışırken “ng-*” şeklinde veya JQuery ile çalışırken “data-*” şeklinde nitelikleri görürüz.

Şimdi bir senaryo geliştirerek biz de kendi tanımladığımız HTML nitelikler aracılığı ile bir uygulama geliştirmeye çalışalım. Bir buton elementi üzerine ekleyeceğimiz netelikleri(attribute) javascript tarafında kullanmaya çalışalım.

<button type="submit"
         data-get-async="true"
         data-url="/products.txt"
         data-attr-target="#getasyncresult">Getir
 </button>

Buton üzerinde data-get-async, data-url, data-attr-target şeklinde tanımladığımız nitelikleri anlamlandırmamız gerekmektedir.

data-get-async: işlemin asenkron gerçekleştirileceğini,
data-url: talebin gönderileceği adresi,
data-attr-target: talep sonrasında dönen cevabın hengi elementi etkileyeceğini belirtiyoruz.

Javascript dosyasını (deneme.js) ise şu şekilde düzenliyoruz:

<script type="text/javascript">

   $(function() {
       var buttonRequest = function () {
       var $button = $(this);
       var options = {
           url: $button.attr("data-url")
      };

      $.ajax(options).done(function(data) {
        console.log(data);
        var $target = $($button.attr("data-attr-target"));
        $target.html(data);
      });
  };

  $("button[data-get-async='true']").click(buttonRequest);
})
</script>

javascript tarafında gerçekleştirdiğimiz işlemi kısaca özetleyecek olursak, yaptığımız şey data-get-async niteliğini barındıran buton tıklandığında yapılacak işlemi belirlemektir.

$(“button[data-get-async=’true’]”).click(buttonRequest);

Bu örnekte “data-*” şeklinde nitelikler tanımlamamın sebebi yardımcı olarak JQuery kütüphanesini kullanıyor olmamdır.

JQuery ajax sorgusu için gerekli url gibi seçenekleri de yine buton üzerinde tanımlanan niteliklere tanımlıyoruz. Geriye kalan ise javascript işlemleridir.

Bu şekilde bir uygulama ile HTML tarafı ile Javascript kod tarafı birbirinden ayrılmış olmaktadır. Yani ön yüz(front end) geliştirme tarafında, Model ve View şeklinde bir ayrım yapılmış olmaktadır. Javascript MVC geliştirme araçlarının yaptığı işlem de bu şekildedir aslında. Direktifleri HTML nitelikeri(attributes) aracılığı ile alır ve komutları çalıştırırlar.

Bir sonraki yazıda görüşmek dileğiyle.

Asp.Net MVC 4 ve Jquery Datepicker uygulaması

26 Ara

Asp.Net MVC 4 uygulamalarında tarih biçimli form elemanlarını seçenekli bir şekilde kullanıcıya sunmak için en etkili yöntem JQuery datepicker UI elementini kullanmaktır. JQuery datepicker elementi ile detaylı bilgiye buradan ulaşabilirsiniz. Dil seçeneklerine kadar bir çok özelliği bu siteden bulabilrsiniz.

date1

Asp.net MVC 4 uygulamamızda tarih biçimindeki bir form elemanına nasıl datepicker özelliği eklendiğini incelemeye çalışacağız.

Hemen bir MVC 4 projesi oluşturarak işe başlayabiliriz. Uygulamımızda formu temsil etmek için rezervasyon adında bir Model tanımlıyoruz.


namespace DatepickerJQueryDemo.Models
{
     public class Reservation
     {
       public string Name { get; set; }
       public DateTime Date { get; set; }
     }
}

Modelimizi kullanmak adına ReservationController adında bir controller ekleyerek devam edebiliriz.


public class ReservationController : Controller
{
     public ActionResult Create()
     {
      return View();
     }
}

ReservationController sınıfımınız Create action metodu bir view döndürmektedir. Bu view içerisinde de create formu ve içierisinde de Name ve Date şeklinde iki metin kutusu olacaktır. Bundan sonraki adımınız Date şeklindeki metin kutusuna datepicker özelliğini katmak olacaktır.

editor

Yapacağımız ilk hamle SolutionExplorer penceresindeki projemizin Views dizinindebulunan Shared dizini içerisine EditorTemplates adında bir klasör ekleyip içerisine DateTime adında bir PartialView eklemek olacaktır.

partialview

EditorRemplates ve DisplayTemplates hakkında daha önceden yazılmış makaleleri buradan inceleyebilirsiniz. Bu işlemi yaptığımızda artık bütün view sayfalarındaki DateTime tipinde olan form elemanları (Html.EditorFor extension metodundan) tanımladığımız bu editör template dosyasını kullanır. Burada dikkat edecek olursak “model DateTime?” şeklinde modelin Nullable tipinde olduğunu belirtiyoruz. Bu belirtimi yapmadığımızda karşılaşacağımız hata mesajı şu şeklide olacaktır.

Hata: The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type ‘System.DateTime’.

Bu hatanın sebebi Create action metodunun view sayfası bir reservation modeline bağlı olamsı, ancak create view sayfasına herhangi bir model nesnesi gönderilmediğinden modelin null olmasıdır. Bu sebeple Datetime nesnesi null şeklinde bir hata mesajı karşımıza çıkar.

Bu ince noktayı belirttikten sonra artık ikinci hamleye geçebiliriz. Bu hamlemiz ise formumuzdaki Date tipindeki text kutusuna JQuery datepicker tarafından kullanılacak olan “data-datepicker” adında bir class eklemek olacaktır. JQuery UI scripti bir elementte bu sınıfı gördüğünde, o elemente datepicker özelliğini yapıştırır.

javascript

Bu javascript kodu, input tipinde olan ve “data-datepicker” sınıfını içieren elementlere datepicker özelliğini ekler. Bir önceki adımımızda TextBox tipine “new{data_datepicker=true}” şeklinde sınıf eklemesini yapmıştık.

Bu javascript kodunu bir js dosyasına kaydedip  Create viewe sayfasına refereans olarak gösterebilirsiniz. Ya da direk Create sayfası içerisine yazabilirsiniz.

Son adımda ise Create view sayfasına jquery.ui dosyasını referens olarak vermek gerekmektedir. Bu dosya isteğe göre _Layout.cshtml sayfasına da referans verebilirsiz. Jquery datepicker  elementinin rengi ve şekline bağlı görünüm özellikleri de Content/themes/base/ jquery-ui.css dosyasında bulunmaktadır. Bu dosyayı da refereans olarak eklemeliyiz.

<link href=”~/Content/themes/base/jquery-ui.css” rel=”stylesheet” />

<script src=”~/Scripts/myscripts.js”></script>

<script src=”~/Scripts/jquery-ui-1.8.20.js”></script>

son

Not: Eğer jquery-ui.js refereansını eklemeyi unutursanız aşağıdaki gibi javascript hataları alabilirsiniz.

Hata: 0x800a01b6 – Microsoft JScript çalışma hatası: Nesne, ‘datepicker’ özelliğini veya yöntemini desteklemez.

Çalışan örnek uygulamaya buradan ulaşabilirsiniz.

Bir sonraki yazıda görüşmek dileğiyle.

JQuery Bildirim Paneli Hazırlama İşlemi

3 Tem

Web dünyasına Javascript’in gücünü gösteren kütüphane olan JQuery, artık geliştiricilerin gözdesi. JQuery sayesinde neler yapılmıyor ki. Özellikle sosyal paylaşım sitelerinde sıklıkla göze çarpan bildirim panelleri benim de dikkatimi çekmedi diyemem. Hemen klavyenin başına geçerek bir iki deneme yapmaya karar verdim ve güzel bir sonuç çıktı ortaya. Dilerseniz beraber inceleyelim.

Web sayfalarında sağ veya sol panellerde, son bildirimleri kayan yazılar şeklinde efektlendiren bir demo yapmaya çalışalım.

Bu işlem için gereksinimimiz bir jquery kütüphanesi referansı ve kodlama için bir ortam. Ben bu uygulama için notepad aracını seçtim. Notepad içerisine html döküman oluşturacak kodları girerek işe başladım ve ardından jquery kodlarını akledim.


<script>

   $(function () {
       setInterval("updateShouts()", 3000);
   });

    function updateShouts() {
       $('#foo').prepend('<div style="display: none;">Yeni içerik.'+Math.random()+'<p><a href="#">İçerik linki</a></p></div>');

       $('#foo').find(".newContent:first").slideDown();

       $('#foo .newContent:gt(5)').remove();
}

</script>

<div id="foo"></div>

JQuery ile bir timer nesnesi kullanılarak, 3 saniyede bir yeni içerik oluşturularak,  panel içerisine eklenmektedir.

Buraya kadar olan işlemler, html bilgisi ve javascript bilgisi ile halledilebilecek şeklide gelişmiştir. Veriler elle üretilmiş ve animasyona sunulmuştur. Tabi gerçek hayat hikayelerinde, yukarıda tanımlanan updateShouts() metodu bir action metoda giderek veri alacak şekilde düzenlenip canlı bir uygulama da hazırlanabilir. Hatta action metod, outputcache mekanizmasıyla desteklenip, gereksiz yere veritabınına gitmeden, direk cache verilerine erişilebilir. Bu da hızda ciddi bir artış sağlar.

Sonuç olarak  yukarıdaki şekildeki gibi bir panel elde edilebilmektedir.

Jquery slide bildirim paneli çalışan uygulamasına buradan ulaşabilirsiniz.