Razor Pages’in adını ilk olarak ASP.NET Core 2.0 Preview 1 çıktığında duymuştuk. İlk çıktığında da oldukça merak uyandırmıştı açıkcası, akıllara da ASP.NET Web Pages’i getirmişti. Sonu onun gibi olursa falan diye biraz çekinerek yaklaşmıştım. Küçük bir kaç PoC için tercih etmem gerekti ve oldukça hoşuma gitti. ASP.NET Core 2.0 da artık son halini aldığına göre biraz daha ayrıntılı bahsetmenin tam zamanı diye düşünüyorum.
Nedir bu Razor Pages?

ASP.NET Core 2.0 ile beraber hayatımıza giren Razor Pages, ASP.NET Core MVC alt yapısında, sayfa bazlı web uygulamaları geliştirebileceğimiz bir programlama modeli. Tamamen MVC alt yapısı üzerine geliştirilmiş bir kabuk olarak düşünebilirsiniz. MVC template’lerindeki klasör sayısını azaltmak, sayfa bazlı uygulamaları daha kolay geliştirmek için tasarlanmış yeni bir model. Altını çizerek belirtmek isterim ki, MVC’ye alternatif ya da onun yerini alacak bir model değil. Genelde yeni bir şey çıkınca bu şekilde soru işaretleri oluşuyor. Ben baştan söyliyim, yok öyle bir şey…

PHP ya da eski ASP ile tecrübesi olanların ya da scripting dilleri ile uygulama geliştirenlerin daha çok hoşuna gideceğini düşünüyorum. Büyük bir ihtimal, web uygulaması geliştirmeyi daha basite indirgemek ve script tabanlı dilleri tercih edenleri de mutlu etmek için böyle bir modele yönelmiş olabilir Microsoft. Ama asıl önemlisi web uygulaması yapmayı yeni öğrenmek isteyen kişileri çekmek sanırım Razor Pages’ın en büyük amacı.Çünkü gerçekten kolay.

MVC alt yapısını kullanarak yapıldığı için uzun zamandır MVC modeli ile geliştirme yapanlar için çok fazla bir şey ifade etmeyecektir. Hatta bir çok MVC tercih eden kişi, ne gerek vardı falan da diyor. Kendilerince haklılar. Burda tekrar belirtmek isterim ki, Razor Pages, MVC’nin bazı özelliklerini daha basit ve kolay hale getiriyor. Uzaya roket gönderebileceğiniz bir teknoloji değil…

Razor Pages, adından da anlaşılacağı üzere “Razor” ve “Sayfa” konsepti üzerine geliştirilmiş bir model. MVC’deki View kavramı, biraz daha geleneksel tabirle “sayfa” olarak karşımıza çıkıyor. Ama tabii ki Layouts, TagHelpers gibi yaklaşımlar Razor Pages’de de var.

Razor Pages’de sayfalar birer PageModel ile tanımlanıyor. PageModel’leri MVC’deki Controller ve Model olarak düşünebilirsiniz. Web sayfanıza gelen talepler(request), Controller’daki gibi PageModel tarafından karşılanıyor. Controller’a ek olarak View tarafına taşınan model de bu PageModel üzerinde olabilmekte.

Razor Pages dosya düzeniDosya yapısı olarak MVC’den biraz daha basit bir yapısı var. Default olarak Pages klasörü altına koyduğunuz *.cshtml’ler sayfalarınızı oluşturuyor. MVC’deki routing ile ilgili uymanız gereken yapı biraz daha basitleştirilmiş. Bir Razor Pages’in tanımlamak için *.cshtml’in @page yol göstericisinin sayfanın başında olması gerekmekte. Benzer bir şekilde @model yol göstericisi ile de sayfanın hangi PageModel sınıfını kullandığı belirtilmek durumunda. PageModel, Razor Pages ile gelen yeni bir abstract sınıf. Geliştirdiğimiz sınıflar, bu sınıftan(PageModel) türemek durumunda. Razor Pages’i sağlıklı kullanmak için geliştirdiğimiz sayfaların modelleri mutlaka bu şekilde olmalı.

Razor Pages’in önemli bir özelliği *.cs(code-behind) dosyası olmadan, *.cshtml’in içinde C# kodu yazarak, sunucu tarafında çalışacak kod ile HTML ve Razor kodlarını bir arada yazabilmeniz. Biliyorum kulağa çok kötü geliyor. Hatta sadece kulağa değil, göze de çok kötü geliyor. Böyle bir özelliğin olması, illa ki o şekilde kullanmanın zorunlu olduğu anlamına gelmiyor. Bu yüzden siz böyle kullanmayın 🙂

Aşağıda örnek bir Razor Pages sayfası görebilirsiniz. Hem code-behind tarafı, hem de Razor ve HTML tarafı bir arada. Burada code-behind tarafındaki kodlarınızın @functions{} yol göstericisinin içerisinde olması gerektiğini belirtmek isterim.

Bu şekilde bir kullanımın bazı kolaylıkları olsa da, belli yazılım prensiplerini uygulamak ve yönetmek zor olacaktır. Kişisel tercihim bu şekilde kullanmak değil. Sunucu tarafında çalışacak kodu ayırmak, benim gibi düşünenler için(biliyorum yanlız değilim 🙂 ) Razor Pages’de tabii ki mümkün. Aynı sayfayı aşağıdaki gibi iki farklı dosyada geliştirebilirsiniz.

Code-Behind tarafı ise;

Handler metotları

PageModel sınıfından türettiğimiz kendi sayfalarımız(Yukarıdaki örnekte IndexModel), az önce yukarda da bahsettiğim gibi sayfaya gelen HTTP request’lerini de işleyen yapıyı içeriyor. HTTP komutlarının başına “On” getirerek yazacağınız metotlar, PageModel’de Handler metotlar olarak tanımlanmakta. Bu metotlar sayesinde  uygulamamıza yapılan request’leri işleyebiliyoruz. OnGet(), OnPost(), OnPut()..vs. gibi.  Aynı zamanda bu metotları asenkron tanımlamak için sonlarına Async getirmeniz yeterli olacaktır. OnGetAsync(), OnPostAsync()…gibi.

Handler metodlar

Kısa bir bakış diye başladım, o yüzden Handler metotlarının çok ayrıntısına girmeyeceğim. Bir sonraki yazıda bunlar ile ilgili daha fazla ayrıntı bulabilirsiniz.

Model Binding…

Özellikle HTTP Post yaparken veri taşımak için, Razor Pages’de [BindProperty] attribute’unu kullanarak data modellerimizi sayfaya bağlamak mümkün. Bu sayede HTML tarafında bu özelliği kullanarak data modelinize ulaşmanız ve verileri taşımanız mümkün. MVC ile çok bir farkı yok, benzer konsept.

Aşağıdaki örnekte User tipinde bir tane WebUser diye bir özellik var. Bu özelliği [BindProperty] attribute’u ile işaretlediğimizde bu özelliğimizi ön yüzde kullanabilir hale geliyoruz.

BindProperty

*.cshtml tarafında ise WebUser.BirÖzellik diyerek, WebUser özelliğimizin verilerine ulaşabiliyoruz.

Razor Pages

Sonrasında sayfaya yapılacak request’lerde bu model üzerinden, HTML formuna girilen verilere erişmek oldukça kolay.

HTML Form

Yukarıdaki gibi basit bir formu POST ettiğimiz zaman, code-behind tarafında tanımlı olan([BindProperty]) modelimize verilerin doğru bir şekilde geldiğini görebilirsiniz.

BindProperty

MVC’den alışık olduğumuz modellerin çeşitli validasyonları yine Razor Pages ile mümkün.

ASP.NET Core 2.0 ile beraber gelen Razor Pages’e kısa bir bakış ile gerçekleştirdik. Umarım biraz olsun fikir vermiştir. İlerleyen yazılarda biraz daha bahsetmeye çalışacağım.