14 Şubat 2019 Perşembe

ASP.NET MVC - Routing

ASP.NET MVC - Routing Nedir ve Nasıl Kullanılır?

Bu yazımda MVC mimarisinde Routing(Yönlendirme) nedir ve kendi route tanımlamalarımızı nasıl yapmamız gerektiğini inceleyeceğiz. ASP.NET MVC’de Routing aslında URI ile action’ın eşleştirilmesinden başka bir şey değildir. 

mvc route ile ilgili görsel sonucu

Routing kodlarına projemizin Global.asax dosyasında RegisterRoutes metodunun altında ulaşabilmekteyiz.

RegisterRoutes metodunun içinde aşağıdaki gibi hali hazırda yer alan bir adet tanımlama göreceksiniz. App_Start klasörün altında RouteConfig.cs classının içinde bulunmaktadır.
public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

   routes.MapRoute(
     name: "Default",//Route adı
     url: "{controller}/{action}/{id}", //URL Pattern
     defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } //Default route
   );
}
MapRoute metodu URL şemasını ve bu URL şemasında hangi controller ve action’ın çalışacağı bilgisini tanımladığınız metotdur. Name ile belirtilen alanda route ismi verilir unique olmak zorundadır. URL ile belirtilen alanda talep olarak gelecek URL yapısı. Default olarakta hangi controller ve hangi action metodunu kullanacağımızı belirtiyor.
Aşağıdaki resimde url adresinin parametreleri gösterilmiştir.
Mvc içinde yönlendirme
Aşağıdaki tablo url adreslerinin hangi Controller,Action ve Id lere karşılık geldiği örneklendirilmektedir.

URLControllerActionId
http://localhost/homeHomeControllerIndexnull
http://localhost/home/index/123HomeControllerIndex123
http://localhost/home/aboutHomeControllerAboutnull
http://localhost/home/contactHomeControllerContactnull
http://localhost/studentStudentControllerIndexnull
http://localhost/student/edit/123StudentControllerEdit123


Multiple (Çoklu)Routes 

Konunun başında  kendi Route tanımlamalarımızı yapacağımızdan bahsetmiştik şimdide bir örnek ile bunu açıklayalım.
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Student",
            url: "students/{id}",
            defaults: new { controller = "Student", action = "Index"}
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
} 
Yukarıdaki kodda gösterildiği gibi, Student route URL modeli , domainName / students ile başlayan herhangi bir URL'nin StudentController tarafından ele alınması gerektiğini belirten students/{id} şeklindedir. URL modelinde {action} belirtmediğimize dikkat edin, çünkü student ile başlayan her URL'nin her zaman StudentController'ın Index eylemini kullanmasını istiyoruz.

MVC framework her route u sırayla değerlendirir. İlk yapılandırılmış route ile başlar ve eğer gelen url route un  URL modelini karşılamıyorsa ikinci route u değerlendirir. Yukarıdaki örnekte, Route motoru önce Student rotasını değerlendirecek ve eğer gelen url  studens ile başlamazsa, yalnızca varsayılan rota olan ikinci rotayı dikkate alacaktır.

Route Constraints(Kısıtlayıcı)
Url parametrelerin değerine kısıtlama uygulanabilir.Örneğin aşağıdaki örnekte id değerini yalnızca sayı girilmesini sağlayabiliriz.(Kısıtlamayı Regular Expressions kullanarak yaptım. Reqular Expressions hakkında detaylı bilgiye buradan ulaşabilirsiniz.)
routes.MapRoute(
        name: "Student",
        url: "student/{id}/{name}/{standardId}",
        defaults: new { controller = "Student", action = "Index", id = UrlParameter.Optional, name = UrlParameter.Optional, standardId = UrlParameter.Optional },
        constraints: new { id = @"\d+" }//sadece numerik karakterler olabilir
    );
Bu makalemde anlatacaklarım bu kadar.Bir sonraki makalede görüşmek üzere.😇😊

13 Şubat 2019 Çarşamba

Asp.net MVC Model Binding


Model Binding Nedir?

    MVC projelerinde View ile Controller arasında veri gönderme işlemlerine ve göndermiş olduğumuz verilerin Model yapısı ile eşleştirilmesi işlemine Model Binding adı verilmektedir. 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.

ASP.NET MVC Model Binding'ın Grafiksel Akışı

Model Binding, Http Requesti ilgili Controler'ün Action Metodu ve Model ile eşleme seçeneği sunar. View , Controller ve Model arasında bir aracı gibi çalışır. Grafiksel akışı aşağıdaki gibidir.

ASP.NET

Eğer bir Action metod parametre almışsa Model Binding işlemi gerçekleşmektedir.
Örneğin aşağıdaki gibi Index adında, string türünde bir tane parametre alan bir Action metod olsun.

  1. public ActionResult Index(string name)  
  2. {  
  3.     return View();  
  4. }  

Index Action’ı çağırılmadan önce arka plan işlemlerini yönetecek iki önemli bileşen vardır. Bunlar ValueProviderDictionary ve DefaultModelBinder’dır.
ValueProviderDictionaryHTTP 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.
  1. public ActionResult Index(int id,decimal rate)  
  2. {  
  3.     return View();  
  4. }  
Bu durumda da DefaultModelBinder sınıfı parametre tip dönüşümlerini otomatik olarak yapacaktır.
Şu ana kadar HTTP request ile gelen isteklerin ayrıştırılıp uygun .NET tiplerine dönüştürüldüğünü anlattım. Ancak bazen de aşağıdaki gibi bir objeyi modele bind etme durumu olabilir 
  1. public ActionResult Index(Insan insan)  
  2. {  
  3.     return View();  
  4. }  
DefaultModelBinder yukarıdaki gibi özel bir .NET tipi ile (Insan) 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.


Model binding işlemini bir örnek ile incelemeye çalışalım. Örneğimizde bir Insan model nesnesinin nasıl bind edildiğini inceliyor olacağız.Aşağıdaki gibi Models Klasörünün içine  bir Insan nesnesi oluşturalım.
  1. public class Insan
  2. {
  3.   public int ID{get;set;}
  4.   public string FirstName{get;set;}
  5.   public string LastName{get;set;}
  6. }


Şimdi de Controller ekleyelim.Ekleme aşamaları aşağıdaki gibidir.

Add New Controller in ASP.NET MVC

Boş  Controllerı seçiyoruz.



İsim verelim.Default kısmına Home  yazalım ve Add diyelim oluşturalım.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVC_BasicTutorials.Controllers
{
    public class HomeController : Controller
    {
        // GET: Insan
        public ActionResult Index()
        {
            return View();
        }
    }
}
Şimdide Controller deki Index e sağ tıklayarak Add View ile View ekleyelim.View tarafında bir form oluşturularak, oluşturulan formun Controller tarafında bir action metoda post edilmesi gerekmektedir.

View in başına aşağıdaki kodu ekleyelim.


@model MvcModelBinding.Models.Insan

Şimdide View in Body kısmına aşağıdaki kodları ekleyelim.
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Kişi Bİlgileri</legend>
   @Html.LabelFor(model => model.FirstName)       
            @Html.EditorFor(model => model.FirstName)
           @Html.ValidationMessageFor(model => model.FirstName)
            @Html.LabelFor(model => model.LastName)
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
            <input type="submit" value="Create" />
   </fieldset>
}
Controller tarafında ise DefaultModelBinder tarafından doldurulmuş Insan nesnesinin kullanılması gerekmektedir.


[HttpPost]
public ActionResult CreateInsan(Insan insan)
{
   // insan nesnesi form bilgileri ile doldurulmuş durumda
   // insan 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 Insan nesnesi DefaultModelBiner tarafından doldurulmuştur.  @model MvcModelBinding.Models.Insan ile view sayfasının modelinin belirlendiğini görüyoruz. Controller tarafında CreateInsan metoduna post edilen form bilgileri Insan nesnesine doldurulmaktadır.
Bu işlem şöyle gerçekleşmektedir: DefaultModelBinder action metodun aldığı parametre tipinden (Insan) bir nesne oluşturarak Property’lerini view sayfasından gelen form bilgileri ile eşleştirerek doldurmaktadır.

Model Binding bu kadar bir sonraki yazıda görüşmek üzere.