ASP.NET MVC Returnurl

24 Nis

Web sayfalarımızda korunan bazı sayfalara yönlendirme yapan bağlantılara(link) tıklandığında, bu sayfanın koruma altında olduğunu belirtmek amacıyla kullanıcıyı sistem giriş sayfasına yönlendiririz. Kullanıcı, giriş yaptıktan sonra en son kaldığı sayfayı hatırlamayabilir. Bu gibi durumlar, genelde forum sayfalarına girdiğimizde karşımıza gelir. İstediğimiz konuyu görmek istediğimizde üye giriş sayfasına yönlendiriliriz ve giriş yaptıktan sonra kaldığımız yerden devam ederiz. Giriş yapıldıktan sonra kaldığımız sayfaya yönlendirilmezsek, tekrar arama motoruna gidip konu linkine tıklamak zorunda kalabiliriz.

Kendi hazırladığımız sistemlerde de bu gibi bir durum başımıza geldiğinde, üye giriş yaptığında son kaldığı sayfaya yönlendirilmesi gerektiğinde ne yapmalıyız?

ASP.NET MVC ile hazırlanan sistemlerde login işlemi sonrası en son geldiğimiz sayfaya yönlendirme yapmak için, en son sayfa URL’i returnUrl adında bir değişkende tutulur.

public ActionResult LogOn(LogOnModel model, string returnUrl)
{
      if (Membership.ValidateUser(model.UserName, model.Password))
      {
         if (!string.IsNullOrEmpty(returnUrl))
         {
              return Redirect(returnUrl);
         }
         else
         {
              return RedirectToAction("Index", "Home");
         }
      }

      return View(model);
}

Eğer returnUrl parametresi boş değilse direk o sayfaya yönlendirme yapılır, boş ise Index sayfasına yönlendirilir.

Bu durumda akla gelen ilk soru “link üzerinde returnUrl parametresi nasıl ayarlanmalı?” olacaktır.

@Html.ActionLink(“Giriş”, “LogOn”, “Account”, new { returnUrl=Request.RawUrl }, null)

Request.RawUrl property’sini returnUrl olarak belirliyoruz. Örneğin ürünler sayfasında bir işlem yaparken, giriş yapılması istenirse, kullanıcı adı ve şifre girildikten sonra tekrar ürünler sayfasına yönlendirilmiş oluruz.

Eğer login işlemi sonrasında direk Index sayfasına yönlendirilsin istiyorsak link aşağıdaki gibi olmalıdır.

@Html.ActionLink(“Giriş”,”LogOn”, “Account”)

Tekrar görüşmek ümidiyler…

Repository Pattern Nedir?

7 Nis

Veri merkezli yazılımların iş katmanlarından veriye ulaşım işlemleri sırasında meydana gelen ve gözardı edilen bazı ayrıntılar, yazılımın ilerki aşamalarında önümüze bir çığ misali yığılıp kalmaktadır. Özellikle katmanlı mimaride geliştirilen yazılımlarda iş kuralları ve katmanlar, düzgün  oluşturulmadığı taktirde bir işi N defa yapmak zorunda kalabiliriz. Ancak nesneye yönelik (object oriented) yapıların ilkelerinden biri de, bir kuralı bir kez belirleyip N kez çalıştırmaktır. Örneğin veritabanındaki öğrenciler tablosuna öğrenci eklemeyi yapan bir nesne ve bir metod olmalıdır.

İş katmanında dikkat edilmesi gereken bazı kurallar vardır. Bunlar:

  • Kod tekrarlarından kaçınmak
  • Hata yakalamayı kolaylaştırmak
  • Kod yazımını ve okunuşunu kolaylaştırmak
  • Test edilebilir bir yapı kurgulamak

Repository pattern de bizi bu kurallara uymaya zorlamaktadır. Peki repository pattern nedir?

Veri merkezli uygulamalarda veriye erişimin ve yönetimin tek noktaya indirilmesini sağlayan bir tasarım desenidir. Veri merkezli uygulama olması şart değil elbette. Ama bu yazıdaki uygulama veriye erişim kurallarını belirleyen bir örnek üzerinden yürütülecektir.

Örneğimiz, bir ASP.NET MVC web uygulaması içerisinden alınmış repository uygulanışını göstermektedir. Verileri, tek noktadan taşıma işlemini yapacak olan repository yapısı da Entity Framework altyapısını kullanmaktadır. Repository pattern için kullanılan teknoloji çokta önemli değildir. MVC veya Entity Framewok gibi detaylara bu örnekte gerek yoktur, yeri gelmişken bahsetmeden geçemedim. İstersek kendi veri katmanımızı (data layer) hazırlayarak da yola devam edebiliriz.

ASP.NET MVC mimarisinin tanıtımı konusunda en etkili örnek olan açık kaynak kodlu Nerddinner uygulaması üzerinden işlemlerimizi yürütmeye çalışacağız. Neden hazır bir uygulama üzerinden gittim? Kendim de bir sınıf hazırlayıp burada kullanabilirdim pek tabi. Ancak, Nerddinner uygulamasını merak edip bakmanızı da istedim, çok faydalı olacağından eminim.

Nerddinner nedir? Hikaye olarak, insanların yemek yiyebilecek yerleri internet üzerinden kaydedebilecekleri veya daha önceden, başkaları tarafından kaydedilen yemek yenilebilecek yerleri görebilmelerini sağlamak şeklinde özetlenebilir. Bu kısmı da yeri gelmişken kısaca özetledikten sonra konumuza dönebiliriz.

Projede yemek yerleri, Dinner tablosunda tutulmaktadır. Entity framework tarafında da, veritabaındaki Dinner tablosu Dinner sınıfı tarafından temsil edilmektedir. Bu noktada Dinner tablosuna CRUD(Create, Update, Delete) işlemlerini gerçekleştirebilmek için bir arayüz (interface) tanımlanır. Bu arayüzü uygulayan(implement) eden sınıflar Dinner tablosuna CRUD işlemlerini yapmaya hazır demektir.

Hazırladığımız interface aşağıdaki gibidir.


public interface IDinnerRepository {

       IQueryable<Dinner> FindAllDinners();
       IQueryable<Dinner> FindDinnersByText(string q);

       Dinner GetDinner(int id);

       void Add(Dinner dinner);
       void Delete(Dinner dinner);

       void Save();
}

Bu arayüzü uygulayan bir sınıfı da aşağıdaki gibi gösterebiliriz.

public class DinnerRepository : NerdDinner.Models.IDinnerRepository
{

       NerdDinnerEntities db = new NerdDinnerEntities();

       Public IQueryable<Dinner> FindDinnersByText(string q)
       {
              return db.Dinners.Where(d => d.Title.Contains(q)
                     || d.Description.Contains(q)
                     || d.HostedBy.Contains(q));
       }

       public IQueryable<Dinner> FindAllDinners()
       {
              return db.Dinners;
       }

       public Dinner GetDinner(int id)
       {
             return db.Dinners.SingleOrDefault(d => d.DinnerID == id);
       }

       public void Add(Dinner dinner)
       {
             db.Dinners.AddObject(dinner);
       }

       public void Delete(Dinner dinner)
       {
            foreach (RSVP rsvp in dinner.RSVPs.ToList())
                db.RSVPs.DeleteObject(rsvp);

            db.Dinners.DeleteObject(dinner);
      }

      public void Save()
      {
            db.SaveChanges();
      }

}

Buradaki NerdDinnerEntities tipi Entity Framework tarafına ait, ObjectContext tipinden türemiş ve kullanıcı tarafından oluşturulan nesneleri alıp kaydetme, güncelleme veya silme işlemleri için oluşturulmuş, motor(engine) görevindeki sınıftır.

Save metodu içerisinde de zaten NerdDinnerEntities tipinin SaveChanges metodu çağrılmıştır ki bu metod, yapılan değişiklikleri veritabanına yansıtır.

Artık Dinner tipindeki bir nesnenin veritabaına kaydedilmesi, güncellenmesi veya silinmesi gibi işlemlerden sorumlu olan sınıf DinnerRepository sınıfıdır. Başka hiçbir yerde bu işlemler için kod yazmaya gerek yoktur. Bir süre sonra, sistemde tarihe göre arama işlemi yapılmak istendiğinde, ilgili metod IDinnerRepository arayüzünde belirlenerek, DinnerRepository sınıfına uygulandığında işlem tamamdır. Tek sorumluluk(Single Responsibility)  DinnerRepository sınıfına aittir. Bu sayede yazılım kurallarından “Tek Sorumluluk” ilkesine de uymuş olduk.

Repository pattern sayesinde test edilebilirlik te mümkün hale gelmektedir. Bu daha ayrıntılı bir konu olduğu için ileriki yazılarımızda işlemeye çalışacağız.

Repository patternle karşılaşmadan önce, kendi kendime desenler oluşturup, tek noktadan veri yönetimini sağlamaya çalışıyordum. Ancak bu desen bana daha düzgün geldi ve artık bu deseni iyice benimsedim. Test gücünü de gördükten sonra vazgeçilmezim oldu. Herkese de tavsiye ederim.

ASP.NET MVC Controller Test Ortamında UpdateModel Davranışları

4 Mar

Bu yazıda ASP.NET MVC ortamında test sınıflarımı hazırlarken karşılaştığım küçük bir ayrıntıyı analtmak istiyorum.  Bu noktadan itibaren kullanacağım örnek ASP.NET MVC3 ortamında yürütülen Nerddinner projesindeki Edit action metod testi olacaktır. Neden Edit action metodunu test ediyorum? Bunun sebebi Edit işlemi sırasında Controller temel sınıfının helper metodları olan UpdateModel veta TryUpdateModel metodlarının özel bir durumunun olması.

UpdateModel helper metodu, form ortamında bir bilgi güncellemesi yapıldığında, formdan  post yöntemi ile gelen değerleri ilgili nesneye bağlamak için kullanılır. Aşağıdaki örnekte görüldüğü üzere FormCollection içierisinden gelen form bilgileri, UpdateModel(dinner) ile dinner nesnesini güncellemektedir.


[HttpPost, Authorize]
public ActionResult Edit(int id, FormCollection collection) {

       Dinner dinner = dinnerRepository.Find(id);

       if (!dinner.IsHostedBy(User.Identity.Name))
            return View("InvalidOwner");

       try {
            UpdateModel(dinner);
            dinnerRepository.Save();
            return RedirectToAction("Details", new { id=dinner.DinnerID });
       }
       catch {
            return View(dinner);
       }
}

O halde bu noktadan sonra şunu anlıyoruz ki test ortamında da UpdateModel metodunu kullanan metodların testi için FormCollction nesnesi kullanmalıyız. Bu güncelleme işlemi nasıl yapılmaktadır? UpdateModel tarafından  Controller sınıfının “ValueProvider” özelliğine bir FormCollection nesnesi atanarak yapılmaktadır.

[TestMethod]
public void EditAction_Should_Redirect_When_Update_Successful() {

      // Arrange
      var controller = CreateDinnersControllerAs("SomeUser");
      int id = 1;

      FormCollection formValues = new FormCollection() {
         { "Dinner.Title", "Another value" },
         { "Dinner.Description", "Another description" }
      };

      controller.ValueProvider = formValues.ToValueProvider();

      // Act
      var result = controller.Edit(id, formValues) as RedirectToRouteResult;

      // Assert
      Assert.AreEqual("Details", result.RouteValues["Action"]);
      Assert.AreEqual(id, result.RouteValues["id"]);

}

Dikkat: FormCollection kullanılmayan test metodları UpdateModel metodunun çalıştırılması(invoke) sırasında NullReferenceException hatası verecektir.

Soru: Eğer Edit action metoduna parametre olarak FormCollection değilde nesnenin kendisi atılsaydı veya bir ViewModel patterne sahip bir nesne gönderilirse ne oladak?

DinnerFormViewModel adında bir nesne ve bu nesne içinde de Dinner tipinde Dinner adında bir property olduğunu varsayalım.


[HttpPost, Authorize]
public ActionResult Edit(int id, DinnerFormViewModel model) {

       Dinner dinner = dinnerRepository.Find(id);
       if (!dinner.IsHostedBy(User.Identity.Name))
            return View("InvalidOwner");

       try {
            UpdateModel(dinner, "Dinner");
            dinnerRepository.Save();
            return RedirectToAction("Details", new { id=dinner.DinnerID });
       }
       catch {
            return View(dinner);
       }
}

Bu durumda UpdateModel metodunun, prefix(ön ek) belirlenebilen versiyonunu kullanıyoruz. Yani DinnerFormViewMolel içerisindeki “Dinner” ile başlayan nesneler “ValueProvider” Property’sine bağlanacak.

Asp.NET MVC 4 Beta Yayınlandı

22 Şub

Microsoft tarafında bir yandan .Net Framework 4.5 hazırlıkları sürerken Asp.Net MVC tarafında da yeni sürüm olan MVC4’te gözükmeye başladı. Bu sürümde MVC3 kullanıcılarının aşina olduğu bazı özellikler geliştirilmiş ve yeni uygulama ortamları eklenmiş durumda.

Başlıca Özellikler

  • ASP.NET Web API
  • Yenilenmiş ve geliştirilmiş proje şablonları
  • Yeni mobil proje şablonları
  • Mobil uygulamaları destekleyen yeni özellikler
  • Otomatik kod üretimleri için yeni tarifler
  • Asenkron metodlar için geliştirilmiş yöntemler

Yeni proje şablon görüntüsü aşağıdaki resimde göründüğü gibi daha şık olmuş.

Proje şablonuna javascrip destekli  yeni pencere açılarak login olabilme gibi özellikler eklenmiş durumda.

Proje ekleme sırasında yeni şablonlar göze çarpıyor. Bu şablonlar, mimariye eklenen yeni özellikleri de temsil etmektedir  aslında.

MVC3 sürümünden farklı olarak Mobile Application sayesinde mobile uygulamalar geliştirmek mümkün, Web API projesi sayesinde ise HTTP servislerini programatik bir şekilde geliştirmek mümkün hale gelmektedir.

Bu yazıda MVC4 için bir göz aşinalığı oluşturmaya çalıştık. İlerki yazılarımızda vakit buldukça diğer özellikleri derinlemesine incelemeye çalışacağız.

 

Asp.net MVC Razor Hepler ile Durum Çubuğu Yapmak

15 Eyl

Bu yazıda tamamen kendi emeklerimizle, jquery veya başka hazır kütüphane yardımı almadan bir ilerleme çubuğu(progres bar) yapmaya çalışacağız.

Yeni bir ASP.NET MVC projesi yaratarak işe başlıyoruz.

Projelerde genellikle ingilizce değişken adları kullanmaya çalışıyorum ki yazının ingilizcesini hazırlarsam çalışan örnek projeyi değiştimeye gerek kalmasın.

Örnek projede içiçe iki div etiketleri kullanıyoruz. Dıştaki div kapsül, içteki div ise durumu göstermeye yarayacak.

Çalışan uygulama görüntüsünü şu şeklide verelim ki daha fazla merak uyandırmadan düşünce geliştirmeye geçelim.

Yukarda görüldüğü gibi iç içe iki div etiketi içersinde son duruma ait yüzdelik gösterim yapılmış durumda.

İlk olarak css dosyamız içerisinde durum göstergesi için gerekli ayarlamalar şu şekilde belirliyoruz.

#progressBar{
   border:1px solid #4771a5;
   height:15px;
}

#progressInner{
   background-color:#96b1d2;
   height:15px;
}

Daha sonra razor view ortamında bir helper kodluyoruz. Helper ise aşağıdaki şekilde olacaktır.

@helper  ProgressBar(double BarWidth, double InnerWidth){

   BarWidth = BarWidth < 0 ? 100 : BarWidth;
   InnerWidth = InnerWidth < 0 ? 100 : InnerWidth;
   BarWidth = BarWidth > 400 ? 400 : BarWidth;

   InnerWidth = InnerWidth > BarWidth ? InnerWidth = BarWidth : InnerWidth;

   string barWidth = BarWidth.ToString() + "px";
   string innerWidth = InnerWidth.ToString() + "px";
   string persantage = ((int)(InnerWidth / BarWidth * 100)).ToString()+"%";

   <div id="progressBar"  style="width:@barWidth">
       <div id="progressInner" style="width:@innerWidth"></div>
   </div>
   <label>@persantage</label>

}

Yukarda ProgressBar adında bir helper oluşturulmuş durumda. Helper içerisinde kullanıcının abuk değerler verip gösterge çubuğunu sapıtmaması için bir dizi önlemler alıyoruz. Bar ve Inner değerinin sıfırdan küçük veremesin, dolan mavi kısım Bar değerini geçemesin v.s gibi. Duruma göre daha fazla önlem alınabilir.

Burada dikkat edilmesi gereken husus şudur ki, html etiketlerinin css özellikleri dinamik olarak değişmektedir.

Geriye kaldı ki bu helper nasıl kullanılacak. O da şu şekilde.


<h2>Razor Helper Progress Bar</h2>

@ProgressBar(300, 120)

Evet sadece bu kadar. ProgressBar helper’ı artık farklı denemelerle kullanılabilir duruma getirdik.

Nerelerde kullanılabilir?

Veritabanından çekilen değerleri göstermek için ideal bir yöntem olabilir. Örneğin bugün en çok satış yapan çalışanın yaptığı satış bugün yapılan toplam satışların yüzde kaçına tekabül ediyor.

Neden bununla uğraşalım?

Çünkü koda tamamen hakimiz. Yukardaki örnekte Bar yüksekliğini css içerisinde sabitledim. İstersek dışarı çıkarıp Width özelliği gibi dinamik hale getirebiliriz.

Soru: Sizce ProgressBar metodunda double parametreler string dönüşümü yapılmadan style içersine nasıl yerleştirilir?

Uygulamanın çalışan kodları buradadır.

Umarım faydalı olmuştur herkese iyi çalışmalar.

Asp.net Mvc Model Binding

5 Eyl

MVC mimarisinde açıklanması gereken bir konu da Model Binding konusudur. Bu yazıda Model Binding konusunu incelemeye çalışacağız.

Tanım: Model Binding HTTP request ile gelen verilerinin ayrıştırılarak ilgili Controller’da bulunan Action metod parametrelerine ve uygun .NET tiplerine dönüştürülmesi işlemidir.

Eğer bir action metod parametre almışsa Model Binding işlemi gerçekleşmektedir.

Arka planda gerçekleşen olaylar: Şimdi aşağıdaki gibi Index adında, string türünde bir tane parametre alan bir Action metod olduğunu varsayalım.

public ActionResult Index(string name)

Index Action’ı çağırılmadan önce arka plan işlemlerini yönetecek iki önemli bileşen vardır. Bunlar ValueProviderDictionary ve DefaultModelBinder’dır.

ValueProviderDictionary: HTTP request ile gelen parametreleri çekerek string halinde depolar. Bu işlem aşağıdaki sırayla gerçekleşir.

  • Request.Form[“name”] var mı diye bakar.
  • Yoksa RouteData.Values[“name”] var mı diye bakar.
  • Yoksa Request.QueryString[“name”] var mı diye bakar.
  • Yoksa null değer döndürür.

Böylece ValueProviderDictionary  HTTP request ile gelen değerleri elde etmiş olur.

DefaultModelBinder: ValueProviderDictionary sınıfının elde ettiği değerleri uygun .NET objelerine gönüştürme görevini üstlenir. Yukardaki örnekte “name” parametresi zaten string tipindedir. Bu durumda DefaultModelBinder dönüşüm yapmak durumunda değildir. Fakat aşağıdaki gibi int veya başka türde parametre alan Action metodlar olabilir.

Durum 1

public ActionResult Index(int id, decimal rate)

Bu durumda DefaultModelBinder sınıfı parametre tip dönüşümlerini otomatik olarak yapacaktır.

Durum 2

Şu ana kadar olan kısımda HTTP request ile gelen isteklerin ayrıştırılıp uygun .NET tiplerine dönüştürüldüğünü gördük. Ancak aşağıdaki gibi özel bir tipin modele bind edilmesi gereken bir durum sözkonusu olabilir.

public ActionResult Index(Person person)

DefaultModelBinder yukarıdaki gibi özel bir .NET tipi ile (Person) karşılaştığında Reflection yardımına koşar. Reflection sayesinde özel tipe ait tüm public özellikler ValueProviderDictionary sınıfı tarafından sağlanan değerleri alır.

Binding

Model binding işlemini bu noktadan itibaren bir örnek yardımıyla incelemeye çalışalım. Örneğimizde bir Person model nesnesinin nasıl bind edildiğini inceliyor olacağız.

public class Person
{
     public int Id { get; set; }
     public string FirstName { get; set; }
     public string LastName { get; set; }
}

Autoproperty’ler yardımıyla oluşturulmuş Person model tipimiz yukarıda basit bir şekilde oluşturulmuş durumda.

View tarafında bir form oluşturularak, oluşturulan formun Controller tarafında bir action metoda post edilmesi gerekmektedir.

@model MvcModelApp.Models.Person 

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Kişi Bİlgileri</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

Controller tarafında ise DefaultModelBinder tarafından doldurulmuş person nesnesinin kullanılması gerekmektedir.

      [HttpPost]
        public ActionResult CreatePerson(Person person)
        {
            // person nesnesi form bilgileri ile doldurulmuş durumda
            // person nesnesi artık gerekli işlem için 
            // (database, xml kaydı v.s) kullanılabilir

            return RedirectToAction("Index", "Home");
        }

Yukarıdaki action metodunun parametresi olan Person nesnesi DefaultModelBiner tarafından doldurulmuştur.  @model MvcModelApp.Models.Person ile view sayfasının modelinin belirlendiğini görüyoruz. Controller tarafında CreatePerson metoduna post edilen form bilgileri Person nesnesine doldurulmaktadır.

Bu işlem şöyle gerçekleşmektedir: DefaultModelBinder action metodun aldığı parametre tipinden (Person) bir nesne oluşturarak Property’lerini view sayfasından gelen form bilgileri ile eşleştirerek doldurmaktadır.

Umarım faydalı bir yazı olmuştur. Herkese iyi çalışmalar. Bir sonraki yazıda görüşmek üzere.

Asp.net MVC ActionMethodSelector Attribute

26 Ağu

Bu yazımızda controller action metodları çalıştığı durumlarda action metodunu kontrol eden kendi attribute sınıfımızı nasıl oluşturabileceğimiz üzerinde duracağız. Kendi özel attribute sınıfımızı oluşturmak için yazdığımız sınıfı ActionMethodSelectorAttribute sınıfından türetmemiz gerekiyor.

Bu sınıf ileri düzeyde oluşturulmuş bir sınıf olacak. Miraslama işlemi ile oluşturduğumuz sınıfa ActionMethodSelectorAttribute sınıfından gelen IsValidForRequest() adında tek bir metod olacaktır.

    public class AjaxMethod : ActionMethodSelectorAttribute

{

public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)

{

if (!controllerContext.HttpContext.Request.IsAjaxRequest())

{

throw new Exception(“Bu metod [” + methodInfo.Name + “] sadece Ajax request için tanımlanmıştır.”);

}

 

return true;

}

}

 

Oluşturulan attribute bir action metoda şu şekilde uygulanmaktadır:

        [AjaxMethod]
        public ActionResult Unknown()
        {
            return View();
        }

Eğer Unknown() metoduna Ajax request haricinde bir request gelirse aşağıdaki gibi bir hata sayfasıyla karşılaşıyor olacağız.

Bir sonraki yazıda görüşmek üzere herkese iyi çalışmalar.

Asp.net MVC Action Kontrolü ve Action Attribute

25 Ağu

Bu bölümde controller sınıfımızdaki action metodları nasıl kontrol edilebileceği vebu metodlara erişim izinlerini belirleyen ve bu metodları bir anlamda özelleştiren bazı attribute’lerden bahsedeceğiz. İnceleyeceğimiz bazı attribute’ler:

  • AcceptVerbs
  • ActionName
  • ActionMethodSelector

AcceptVerbs Attribute

Bu attribute action metoduna HTTP operasyonları yardımıyla erişme izinlerini belirler. Bir action metoduna sadece HTTP Get metoduyla ya da Post metoduyla erişilmesini isteyebiliriz. Bu durumda ilgili action metodumuz AcceptVerbs attribute ile işaretlememiz gerekecektir.

Bir employee controller sınıfımıza ait Create() metodu olduğunu varsayacak olursak bu noktada iki adet Create() action metoduna ihtiyacımız olacaktır. Birinci metod HTTP GET operasyonu ile metodu ile çağrılmalı ve form sayfasını karşımıza çıkarmalı, ikinci metod ise form doldurulduktan sonra HTTP POST metodu ile verilerin alınarak işlenmesini sağlayacaktır.

// GET: /Employee/Create

[AcceptVerbs(HttpVerbs.Get)]

public ActionResult Create()

{

return View();

}
// POST: /Employee/Create

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Create(Employee employeeToCreate)

{

try

{

//Kayıtları yap…

return RedirectToAction(“Index”);

}

catch

{

return View();

}

}

Bu durumda bowser ortamından /Employee/Create şeklinde çağırdığımızda eğer controller oluşturulmamışsa hata raporu gözükecektir.

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly.

Requested URL: /Employee/Create

Bu hatanın sebebi, henüz Employee adında controller oluşturulmamış olmasıdır.

Employee adında bir Controller oluşturulduktan sonra ve bir Create action metod oluşturulursa sorun çözülmüş olacaktır.

Action metodlarını HTTP operasyonlarıyla işaretlemenin bir diğer yolu ise aşağıdaki şekildedir. [AcceptVerbs(HttpVerbs.Post)] yazımının kısa yazılmış şeklidir.

        [HttpGet]
public ActionResult MyAction()

{

return View();

}

Bu metod daha kullanışlıdır. Hazır oluşturulmuş attributeler yazdımıyla işaretlemeler yapılmaktadır.

HTTP operasyonlarından en çok bilinen POST ve GET operasyonlarıdır. Diğer operasyonlar DELETE, PUT, HEAD, TRACE, CONNECT.

Asp.net MVC 4 Yol Haritası

24 Ağu

Microsoft ASP.NET MVC 4 Yol haritasını yayınladı. Tabi bu yol haritası üzerinde değişklikler yapılabilmesi muhtemel geçici bir bakış açısı gibi duruyor. Bu yol haritasında dikkat çekici üç hazırlık mevcut. Bunlar yeni araçlar (tooling), genişletilmiş mobil platform desteği ve bulut tabanlı (cloud based) çözümler.

ASP.NET MVC takımındaki bir diğer çalışma ise Genişletilebilir Görev Tabanlı Araçlar (Recipes = (Extensible Task-Based Tooling). Örneğin view katamnında bir datagridi doldurup göstermek için önce data-access sınıfları hazırlanır, sonra controller tarafında veriler bir model doldurulur ve view katmanına sunulur. Bu çözümler (Recieps) denilen araçlar bu işlemlere yardım edecek. Kullanıcılar kendi çözümlerini de kendileri yazabilecekler. Yazılan çözümler bir arayüz vasıtası ile uygulamaya dahil edilebiliyor olacak.

Smartphone ve tablet tarafından olaya baktığımızda Microsoft ASP.NET MVC takımı template vb. yöntemlerle ASP.NET MVC 4 web sayfalarının mobil versiyonuna daha iyi destek vermeyi düşünüyor. Aşağıda MVC3 ve MVC4 ile yapılmış web sitelerinin mobil ortamda görüntülerini incelediğimizde farkı daha iyi anlamış olacağız.


Ele alınan bir başka değişiklik ise özellikle tablet ve mobil cihazlar için yeni bir proje şablonu. Bu şablonun da görünümü yine aşağıdaki gibi olacak:


Tabi bu kadarla da kalmayıp aygıta göre View oluşturma imkanı da gelen yeni yenilikler arasında. Örneğin mobil aygıtlar için oluşturulan bir View .mobile uzantılı olacak. Aşağıdaki resimde view katmanının görünümü verilmiştir:

Asp.net MVC ve ELMAH ile Hata Log Kaydı

22 Ağu

Web uygulamalarımızı yaparken tüm kontrol elimizde olsun isteriz. Kontrol etmek istediğimiz noktalardan birisi de süreç işlerken oluşan hataların neler olduğudur. Yani bir kullanıcı sistemde işlem yaparken bir hata ile karşılaştığında işleminin neden yarıda kesildiğinden haberdar olmak isteriz. Yazdığımız kodlardaki bug’lar olsun, sunucu kaynaklı sorunlar olsun sorunun ne olduğu, ne zaman meydana geldiği hatta hangi kullanıcının bu sorunu yaşadığı kaydedip incelemek istediğimiz durumlardır.

Bu noktada yazılmış hata yöneticilerinden biri de ELMAH (Error Logging Modules and Handlers) kütüphanesidir. Bu kütüphane süreç işlerken oluşan hataları detaylı olarak kaydeder.

Oluşan Log kayıtlarını birçok ortamda depolayabiliriz. Bu depolama ortamları:

Burada dikkat etmemiz gereken noktalardan biri oluşan hata loglarını nereye kaydedeceğimizi belirlemektir. Biz kayıtları XML dosyada tutacağız.

ASP.NET MVC projesine ELMAH kütüphanesini dahil etmek için Nuget Package Manager eklentisini kullanıyor olacağız.

Package Manager Console açarak Install-Package elmah.xml komutunu giriyoruz. Kurulum otomatik olarak gerçekleşiyor. Web.config dosyası içerisinde ayarlamalar otomatik olarak yapılıyor. Hata kayıtlarının nerede tutulacağını belirleyen kısım ise aşağıdaki gibidir.

  <elmah>   
    <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data/Elmah.Errors" />
  </elmah>

Yükleme işlemi gerçekleştikten sonra HomeController içersine About adında bir index belirliyoruz ve bu metodun hata fırlatmasını sağlıyoruz.

 

http://localhost:1735/Home/About şeklinde çağırdığımızda meşur sarı hata sayfasıyla karşılaşıyoruz. (1735 portu kendi makinamın verdiği port numarası, sizin denemenizde bu numara farklı olabilir.)

Bu hata kaydı  App_Data/Elmah.Errors dizininde XML dosya içersine kaydedilmiş olacak. Hata kaydını görmek için http://localhost:1735/elmah.axd yoluna bakıyoruz ve aşağıdaki şekilde başarılı sonuca ulaşmış oluyoruz.