'ASP.NET MVC Framework' Kategorisindeki Makaleler


MVC Framework Önerileri 1 - AbstractController

MVC Framework iyiden iyiye büyük projelerde kullanılmaya başlandı. Hoş ben çıktığından beri istisnasız kullanıyorum =) Web Form ne demekti unuttum sayılır :P Ancak MVC bize hazır bir pattern getirse bile yine de bazı eksiklikleri ve bizim dikkat etmemiz gereken noktaları var. Bahsedeceğim nokta Controller yapımızla ilgili.

Sorunu anlamak için başımdan geçen örnek bir senaryo vereyim: 
Geliştirdiğimiz bir sitenin aynı fiziksel site üzerinden birden çok müşteriye hizmet vermesi isteniyor. Müşterilerin bir listesi konfigürasyon xml’i olarak saklanacak ve gerekli bilgiler buradan alınacak. Ancak gelen isteğin hangi müşteriye ait olduğunu subdomain kullanarak anlamamız gerekiyor.

Bu problemin çözümü tek controller kullandığımız zaman oldukça kolay. Ancak birden çok controller bulunması halinde, tüm controllerlar ve bu controllerlar içerisindeki tüm actionlar için aynı işlemin yapılması gerekecek. DRY (Don’t Repeat Yourself) Principle bize ne demekte: Eğer uygulamanızda tekrarlayan kodlar varsa tasarımı gözden geçiriniz. Şimdi bu sorun (ve tabi ki benzer mantığa sahip diğer tüm sorunlar) için kullanılan çözümü inceleyelim: Abstract Controller.

Yukarıdaki class diagramın göstermekte olduğu gibi elimde iki adet controller var, Home ve Help. Bu controllerlar ortak olarak AbstractController sınıfından türemekteler. Peki controller olma özelliklerini kaybettiler mi? Hayır çünkü temel AbstractController sınıfı Controller’dan türemekte.

AbstractController.cs


public abstract class AbstractController : Controller
{
     public string CustomerName { get; set; }
 
     protected override void OnActionExecuting(ActionExecutingContext filterContext)
     {
         base.OnActionExecuting(filterContext);
 
         //url'den ayırma işlemi yapıldığını varsayıyoruz
         CustomerName = "Yüce Çelikel";
         ViewData["CustomerName"] = CustomerName;
     }
}

Görüldüğü gibi AbstractController içerisinde CustomerName isminde bir özellik tanımladık. Bunun yanında OnActionExecuting metodunda ViewData içerisine bu CustomerName’i yerleştirdik. OnActionExecuting metodu bir action çalıştırılmadan önce yapılacak işlemleri belirlememizi sağlar. Bu metot AbstractController içerisinde tanımlandığı için artık bu sınıftan türeyen tüm Controllerlar çalıştırılmadan önce ViewData içerisine müşteri bilgisi eklenecek. Eğer bilgi çıkarma algoritmasında bir değişiklik olursa tek tek tüm controllerları ellemek zorunda kalmayacağız ;)

Ben AbstractController üzerine bir de AbstractDbController koyarak database erişimi olacak olan controllerı da ayırmayı tercih ediyorum. Her controller illa ki bir data kaynağı nesnesi oluşturmak zorunda değil ne de olsa ;)

Şimdilik bu kadar arkadaşlar. Zaman buldukça aklıma gelen önerileri ve bilgileri yine paylaşacağım buradan. Esen kalın..

Anahtar Kelimeler MVC, AbstractController
Dosyalar

Custom ActionResult Hazırlama (ImageResult)

ASP.NET MVC teknolojisinin en güzel yanlarından biri de neredeyse her Microsoft teknolojisi gibi genişletilebilir olması. Şimdi genişletme işlemi için belki de en çok kullanacağınız işlem olan kendimize özel ActionResult hazırlama yöntemini göreceğiz.

ActionResult sınıfı bir action metodunun kompleks işlemler yapan bir sonuç gerektirmesi durumunda kullanılır. Bu sınıf bir abstract class olduğu için nesne alınamaz. Zaten içerisinde de tek metot bulunmaktadır : ExecuteResult. Bu metot ActionResult ile yapılan işlemlerin çalıştırılması için kullanılır. Bizim kullandığımız ViewResult, FileResult, RedirectResult, JsonResult gibi tüm resultlar ActionResult sınıfından türerler. Bu durumda biz de kendi resultlarımızı oluşturabiliriz. Tek yapmamız gereken ActionResult sınıfından türeyen ve ExecuteResult metodunu override eden bir sınıf hazırlamak.

Örnek :

Custom Result Solution

Örneğimde site üzerinde belirli bir klasörde bulunan (Content/Images)  bir resmin görüntülenmek üzere img etiketine sağlayacak olan bir ImageResult hazırlayacağım. Bu result sınıfını da AlbumController isimli controllerda GetSingleImage isimli bir action içerisinde kullanacağım. Action metodumuz istediği resmin sadece ismini parametre olarak alacaktır. Bu örneğe uyacak şekilde hazırladığım AlbumController ve ImageResult kodları aşağıda verilmiştir.

using System;
using System.Web;
using System.Web.Mvc;
using System.Drawing;
using System.Drawing.Imaging;

namespace CustomActionResult.Controllers
{
    public class AlbumController : Controller
    {
        public ImageResult GetSingleImage(string isim)
        { 
            string url = String.Format("~/Content/Images/{0}", isim);
            return new ImageResult() { ImageUrl = url, Format = ImageFormat.Png };
        }
    }

    public class ImageResult : ActionResult
    {
        public string ImageUrl { get; set; }
        public ImageFormat Format { get; set; }
        
        public override void ExecuteResult(ControllerContext context)
        {
            Image sonuc = GetImage(context);
            HttpResponseBase response = context.HttpContext.Response;

            //response içeriğini ayarlama. resim türü Format özelliğinden alınmaktadır
            response.ContentType = String.Format("image/", Format);

            //resmi client'a gönderilecek bilgileri oluşturan Response'a yazma
            sonuc.Save(response.OutputStream, Format);
        }

        protected Image GetImage(ControllerContext context)
        {
            if (!String.IsNullOrEmpty(ImageUrl)) //resim adresi verilmişse adresten resmi yükle
            {
                string url = context.HttpContext.Server.MapPath(ImageUrl);
                return Image.FromFile(url);
            }
            else //her iki parametre de geçersizde hata fırlat
            {
                throw new ArgumentException("Resim adresi veya resim verilmemiş");
            }
        }
    }
}

Resmi Response üzerine yazma şeklimiz klasik ASP.NET’ten alışık olduğumuz bir kullanım. Görüldüğü gibi MVC, ASP.NET mimarisinin üzerine son derece uyumlu olacak bir şekilde tasarlanmıştır.

Bu controllerı kullandığım sayfa kodları ise aşağıdaki gibidir. Görüleceği üzere tek yaptığım img etiketine kaynak olarak Url.Action metodunu kullanarak legendary.jpg isimli dosyayı vermektir.

<%@ Page Language="C#"  Inherits="System.Web.Mvc.ViewPage" %>

<html>
    <head>
        <title>Custom Action Result</title>
    </head>
    <body>
        <h2>Album Resim</h2>    
        <img src="<%= Url.Action("GetSingleImage", "Album", new { isim = "legendary.jpg" }) %>" />
    </body>
</html>

Çıktı olarak ise aşağıdaki görüntüyü elde ederiz. Görüntüde legendary isimli resmin gözükmesi hazırladığımız ImageResult sınıfının başarılı olduğunu göstermektedir.

Anahtar Kelimeler ASP.NET MVC ActionResult ExecuteResult ImageResult
Dosyalar Custom ActionResult.rar

ASP.NET MVC'de JsonResult ve JQuery Yardımıyla AJAX

Bu makalemde sizlere ASP.NET MVC  kullanarak Jquery yardımıyla nasıl AJAX işlemi yapılabileceğinden bahsedeceğim.  İhtiyacımız olacak olan elementler ise jquery script dosyası ve ASP.NET MVC projesi olacaktır.

Bilindiği üzere AJAX denilen kavram javascript kullanılarak tarayıcı arkaplanında server üzerine bir istek yapmak ve istekten dönen sonucu DOM üzerine yansıtmaktır. Tarayıcı üzerinde yazdığımız javascript kodlarını kısaltmak ve işimizi kolaylaştırmak amacıyla JQuery kütüphanesi geliştirilmiştir. Bizim inceleyeceğimiz nokta ise Jquery’e ASP.NET MVC kullanarak nasıl veri sağlanacağıdır. AJAX işlemlerinde veri transferi için XML veya daha ufak boyutlara sahip ve javascript ile entegrasyonu kolay olan JSON kullanılır. Makalemizde transfer amacıyla JSON kullanılacaktır.

ASP.NET MVC mimarisinde controllerlar client’a gönderilecek olan cevap türünü yönetmekle sorumludurlar. Ancak geriye sadece sayfa çıktıları olarak HTML gönderilebildiğini düşünüyorsanız yanılıyorsunuz. Geri dönüş bilgiler bir string, resim, dosya veya örneğimizde kullanacağımız JSON olabilir. Bütün bu türler için MVC Framework içerisinde ActionResult sınıfından türemiş bazı sınıflar bulunmaktadır ve bu türler cevap gönderme işlemleriyle sorumludurlar. Client’a JSON verisi gönderebilmek için hazırlayacağımız action metodunun geri dönüş türü JsonResult olmalıdır. Herhangi bir nesnenin JSON karşılığını hazırlamak için de temel Controller sınıfından gelen Json() metodu kullanılmalıdır.

Örneğimizde bir dizi içerisinde saklanan isim listesinde arama yapacak ve koşulu sağlayan isimleri JSON formatına göre dizi olarak yollayacağız. Bu amaçla aşağıdaki Controller ve içerisinde de Listele action’ı yazılmıştır.

HomeController.cs :

using System;
using System.Web.Mvc;

namespace Mvc_Ajax.Controllers
{
    public class HomeController : Controller
    {
        //isim önerilerinin getirileceği isim dizisi
        string[] isimler = { "Yüce", "Çelikel", "Hakkı", "Nefise", "İrfan", "Sercan" };

        public ActionResult Index()
        {
            return View();
        }

        public JsonResult Listele(string isim)
        {
            string[] sonuc = null; //sonuçların yazılacağı dizi

            if (!String.IsNullOrEmpty(isim))//eğer gönderilen değer boş değilse
                sonuc = Array.FindAll(isimler, s => s.Contains(isim));//içerisinde yollanan değer 

geçen tüm 

değerleri bul
            else
                sonuc = isimler;//eğer gönderilen değer boşsa tüm seçenekleri yolla
            
            //diziyi json formatına çevirme ve geri döndürme
            return Json(sonuc);
        }
    }


Listele metodu client tarafından gönderilecek isim türünden bir parametreyi alacak şekilde tasarlanmıştır. Eğer gönderilen isim değeri boş veya null ise dizi içerisinde tüm elemanlar geriye yollanır. Ancak boş değilse dizide gönderilen değeri taşıyan elemanlar bulunur ve bunlardan oluşan bir liste client’a yollanır. En son satırda da görüleceği gibi oluşan string[] dizisi Json metoduna parametre olarak verilir ve çıktı JSON türünde kullanıcıya yollanır.

Arayüzümüzde ise bir textbox ve listbox kullanıyoruz. Textbox içerisindeki değer değiştiğinde AJAX işlemi yapılır ve Listele action’ı  çağırılır. Eğer işlem başarılıysa sonuç alınır ve eval() fonksiyonu kullanılarak bir javascript dizisi haline çevrilir. Daha sonra da bu dizinin her bir elemanı için listbox içerisinde bir seçenek (option) eklenir. Dizi elemanlarının her biri için aynı işlemin yapılmasını bir jquery kolaylığı olan each() fonksiyonu ile sağlıyoruz.

Home.aspx :

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<html>
    <head>
        <script type="text/javascript" src="../../Scripts/jquery-1.3.2.js"></script>
        <style type="text/css">
            label
            {
                display:block;    
            }
        </style>
    </head>
    <body>
        <!-- isimleri textbox verisine göre listeleme -->
        <label>İsim :</label> 
        <%= Html.TextBox("Isim") %><br />
        
        <label>Seçenekler :</label>
        <select size="5" id="Secenek" style="width:150px">
        </select>
        
        <script type="text/javascript">
            $(document).ready(function() {
                //Isim textbox'ına klavye tuşuna basıldığında
                $("#Isim").keyup(function() {
                    
                    //ajax işlemi yaparak eşleşen isim listesini al
                    $.ajax({
                        url: "/Home/Listele?isim=" + $(this).val(), //bu adrese id ismindeki parametrenin değeri 

olarak textbox'ın değerini yolla
                        dataType: "json", //geriye json türünde veri dönecek
                        type: "GET", //bu GET türünde bir istek olsun
                        success: function(result) { //işlem başarılı oursa
                            $("#Secenek").html(""); //eski seçenekleri temizle
                            var isimler = eval(result); //json verisini javascript nesneleri haline getir

                            //her bir isim için seçeneklere yeni bir option ekle
                            $.each(isimler, function(count, item) {
                                $("#Secenek").append("<option>" + item + "</option>");
                            })
                        },
                        error: function() { //hata oluşursa ekranda mesaj göster
                            alert("İsim listesi okumada hata oluştu");
                        }
                    })
                });
            });
        </script>
    </body>
</html>

Yukarıdaki kodları çalıştırdığımız zaman aşağıdaki arayüzü ve textbox içerisine yazı yazdığımız zaman da yandaki resimdeki görüntüyü elde ederiz.

JsonResult ile AJAX   JsonResult ile AJAX

Yüce ÇELİKEL
MCPD Enterprise Developer 

Anahtar Kelimeler ASP.NET MVC Framework JSON JsonResult AJAX JQuery
Dosyalar Mvc_Ajax.rar