19 Temmuz 2014 Cumartesi

MVC Film Uygulaması - Veritabanına Erişim (Part V)

Bu yazımızda, film verilerini getiren ve bir view şablonu kullanarak tarayıcıda gösteren yeni bir FilmlerController sınıfı oluşturacağız.

Öncelikle uygulamamızı derleyelim. Eğer hata alıyorsak, gerekli controller'ı eklemediğimizden kaynaklıdır.

Derleme işlemimiz tamamlandıktan sonra Solution Explorer'a gelelim ve Controllers klasörüne sağ tıklayalım ve devamında Add > Controller diyelim:


Add Scaffold diyalog kutusunda, MVC 5  Controller with views, using Entity Framework'ü seçelim ve Add'e tıklayalım.


Çıkan Add Controller penceresinde:
  • Controller name kısmına FilmlerController,
  • Model sınıfı olarak Film (MVCFilm.Models)'ı seçelim
  • Data context sınıfı olarak da FilmDBContext(MVCFilm.Models)'ı seçelim.
Aşağıdaki şekilde girdikten sonra Add'e tıklayalım.


Visual Studio bizim için aşağıdaki dosya ve klasör oluşturdu:

  • Controllers klasöründeki FilmlerController.cs,
  • Views\Filmler klasörü,
  • Views\Filmler klasörü altında Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml ve Index.cshtml.

Visual Studio otomatik olarak CRUD (create, read, update, delete) action metodlarını ve view'lerini oluşturdu (otomatik olarak CRUD metodlarının ve view'lerinin oluşturulması işlemine scaffolding (iskele oluşturma) denir). Artık film oluşturma, listeleme ve silmemizi sağlayan tam fonksiyonlu bir web uygulamasına sahibiz.


Uygulamamızı çalıştıralım ve MVC Film linkine tıklayalım (veya adres çubuğundaki URL'in sonuna /Filmler ekleyerek Filmler controller'ına göz atabiliriz). http://localhost:xxxxx/Filmler isteği bizi Filmler controller'ındaki varsayılan Index action metoduna yönlendiriyor. Çünkü şu an uygulamamız RouteConfig.cs dosyasında tanımlanan varsayılan yönlendirmeyi kullanıyor. Yani diğer bir deyişle tarayıcıya gelen http://localhost:xxxxx/Filmler isteği ile http://localhost:xxxxx/Filmler/Index isteğine aynı şekilde muamele yapılıyor. Henüz eklemediğimiz için film listesi şu an boş görünüyor.

Film Oluşturma

Create New linkine tıklayalım ve istediğimiz bir film hakkında detayları girelim ve Create tuşuna tıklayalım:


Not: Fiyat kısmını benim yaptığım gibi virgül ile girmiş olabilirsiniz. Fakat jQuery varsayılan olarak bunu desteklemiyor. Bunu yapabilmek için https://github.com/jquery/globalize adresinden indirebileceğiniz globalize.js dosyasını projenize dahil ederek Globalize.parseFloat kodunu ekleyebilirsiniz. Bunu aslında sonraki yazımızda ele alacağız. Fakat şimdilik ondalık sayıları nokta ile ayırmaya devam edebilirsiniz. Tarih kısmı için de aynı şey geçerli. Amerikan formatı olan Ay-Gün-Yıl şeklinde girmemiz gerekiyor.

Create butonuna tıkladığımız taktirde oluşturduğumuz form, veritabanında film bilgilerinin tutulduğu sunucuya gönderilecek. Devamında /Filmler sayfasına tekrar yönlendirileceğiz ve yeni oluşturduğumuz filmin listede yer aldığını göreceğiz.


Birkaç tane daha film girebiliriz. Tamamen çalışır halde bulunan Edit, Details ve Delete linklerini deneyebiliriz.

Oluşturulan Kodları İnceleyelim

Controllers dizininde yer alan FilmlerController.cs dosyasını açalım ve otomatik olarak oluşturulmuş Index metodunda göz gezdirelim.

public class FilmlerController : Controller
{
    private FilmDBContext db = new FilmDBContext();

    // GET: /Filmler/
    public ActionResult Index()
    {
        return View(db.Filmler.ToList());
    }
FilmlerController'ına gelen istek, Filmler tablosundaki bütün girdileri çekiyor ve Index view'ına aktarıyor. Aşağıdaki kod satırında, daha önce de bahsettiğimiz gibi FilmDBContext'in bir nesnesi oluşturuluyor. Bu sayede FilmDBContext'i kullanarak filmleri çekebilir, düzenleyebilir ve silebiliriz.

private FilmDBContext db = new FilmDBContext();

Strongly Typed Model'lar ve @model İfadesi

Bu yazı dizisinin önceki kısımlarında controller'ın ViewBag nesnesi kullanarak verileri nasıl view şablonuna aktardığını görmüştük. ViewBag bir view'a verileri iletmek için uygun bir yöntem sağlayan dinamik bir nesneydi. Fakat ViewBag kullanırken IntelliSense olmadığı için, hangi veriyi aktaracağımızı göremediğimizden dolayı düzgün bir şekilde kodlamamız gerekiyordu.

Bu yüzden MVC, strongly typed nesnelerin view şablonlarına aktarılmasını sağlar. Strongly-typed (kesin tür belirtimi) yaklaşımı, kodumuzu derlenme-zamanında daha iyi kontrol etmemizi ve Visual Studio ortamında daha zengin bir IntelliSense oluşmasını sağlar.  FilmlerController sınıfı ve view şablonlarında metodlar ve view'lar oluştururken Visual Studio'daki scaffolding mekanizması bu yaklaşımı kullandı.

Controllers\FilmlerController.cs dosyasında oluşturulan Details metoduna yakından bakalım:
public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Film film = db.Filmler.Find(id);
    if (film == null)
    {
        return HttpNotFound();
    }
    return View(film);
}
id parametresi genellikle yönlendirme verisi olarak gönderilir.Örneğin http://localhost:1234/filmler/details/1 URL'i, controller olarak FilmlerController'ı, action olarak details'i, ve id olarak 1'i seçer. id'yi ayrıca şu şekilde de URL'e aktarabiliriz:

  • http://localhost:1234/movies/details?id=1

Eğer bir Film bulunduysa, Details view'ına gönderilir.
return View(film);
Views\Filmler\Details.cshtml dosyasını inceleyelim:

@model MVCFilm.Models.Film

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
    <h4>Movie</h4>
 <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Baslik)
        </dt>
         @* Daha okunaklı olması için devam eden satırları atladım *@        
    </dl>
</div>
<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
    @Html.ActionLink("Back to List", "Index")
</p>
View şablonu dosyasının üstündeki @model'ı ekleyerek, view'ın beklediği nesneyi belirleyebilriz. FilmController'ı oluşturduğumuzda, Visual Studio otomatik olarak Details.cshtml dosyasının üst kısmına aşağıdaki @model ifadesini ekledi.
@model MVCFilm.Models.Film
@model ifadesi, controller'dan view'a aktarılan filme, strongly-typed bir Model nesnesi kullanarak erişmemizi sağlıyor. Örneğin Details.cshtml şablonunda, her film özelliği strongly-typed Model nesnesi kullanılarak DisplayNameFor ve DisplayFor ismindeki HTML Helper'larına aktarılıyor.

MoviesController.cs dosyasındaki Index metodunu inceleyelim. Dikkat edersek Index action metodu içerisindeki View helper metodu çalıştırıldığında bir liste yaratılıyor. Devamında bu film listesi Index metodundan view'a aktarılıyor.

public ActionResult Index()
{
    return View(db.Filmler.ToList());
}

FilmController'ı oluşturduğumuzda, Visual Studio otomatik olarak Index.cshtml dosyasının üst kısmına aşağıdaki @model ifadesini ekledi:
@model IEnumerable<MVCFilm.Models.Film> 
Yukarudaki @model ifadesi, controller'dan view'e gelen filmlerin listesine strongly typed Model nesnesi kullanarak erişmemizi sağlar. Örneğin Index.cshtml şablonundaki kod parçasında, strongly typed Model nesnesi üzerinde foreach ile gezebiliyor.
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Baslik)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.CikisTarihi)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Tipi)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Fiyati)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
            @Html.ActionLink("Details", "Details", { id=item.ID })  |
            @Html.ActionLink("Delete", "Delete", { id=item.ID }) 
        </td>
    </tr>
}
Model nesnesinin strongly typed (IEnumerable<Film> türünde) olması nedeniyle, döngü içerisindeki her item nesnesi bir Film tipindedir. Bu sayede derleme-zamanında kodun kontrol edilmesi ve kod editörde tam bir IntelliSense desteğinin olması mümkün hale gelmiştir.


SQL Server LocalDB

Entity Framework Code First, veritabanımız olmadığı halde, Filmler veritabanının connection string'ini eklediğimiz için, otomatik olarak durumu tespit etti ve veritabanını oluşturdu. App_Data klasörüne bakarak veritabanımızın oluşturulduğunu görebiliriz. Fakat şu an boş görünüyor. Bunun için Solution Explorer araç çubuğundaki Show All Files düğmesine tıklarsak, App_Data klasörünü genişlettiğimiz taktirde mdf tipindeki dosyamızı görüyor olacağız.


Server Explorer'ı açmak için Films.mdf dosyasına çift tıklayalım. Tables klasörünü de açtığımızda Filmler tablosunu görebiliriz. ID'nin yanında nedense bir anahtar ikonu var. Bunun nedeni, EF'in varsayılan olarak ID isimli özelliği primary key yapmasıdır.



Oluşturduğumuz filmleri görmek için Films tablosuna sağ tıklayalım ve Show table Data'yı seçelim.



Entity Framework Code First'ün bizim için oluşturduğu tablo yapısını görmek için Films'e sağ tıklayalım ve Open Table Definition'ı seçelim.


Films tablosunun şemasına bakarsak, daha önceden oluşturduğumuz Film sınıfı ile eşleşmiş görünüyor. EF Code First otomatik olarak Film sınıfına bakarak bu şemayı oluşturdu. Ardından da çoğul bir ifade olması için '-s' takısı ekledi

Veritabanıyla işimiz bittiğinde FilmDBContext'e sağ tıklayıp Close Connection'ı seçerek kapatalım. Aksi taktirde projemizi çalıştırdığımızda hata alabiliriz.


Artık bir veritabanımız ve verileri göstermek, düzenlemek ve silmek için kullanabileceğimiz sayfalarımız var. Sonraki yazımızda otomatik olarak oluşturulan kodun tamamını inceleyeceğiz ve veritabanında filmleri arayabilmemizi sağlayacak Arama metodunu ile Arama view'ını ekleyeceğiz.

Kaynaklar: ASP.NET












Hiç yorum yok:

Yorum Gönder