Basit bir mvc projemisinin dizin yapısı

  • App_Data : Proje içerisinde ki veritabanı vb. veri kaynaklarının, dosyalar halinde eklendiği klasördür.
  • App_Start : Projenin ilk açılışı esnasında (sunucunun ilk başlatılışı ya da yeniden başlatılması), işlem yapması istenilen sınıfların, filtrelerin, metodların bulunduğu klasördür. Örneğin Route, yani sayfa yönlendirme dosyasının ya da projeye eklediğimiz JavaScript, Css gibi dosyaların sıkıştırılarak istemciye gönderilmesi mimarisi olan BundleConfig gibi dosyaları burada barındırırız.
  • Content : Bu klasör, zorunlu olmamakla birlikte genelde css dosyaları bu klasörde barındırılabilir.
  • Controllers : Controller dosyalarının barındırıldığı klasördür.
  • fonts : Asp.Net Mvc 5 sürümü ile birlikte, örnek projeye eklenen (bu klasörü kullanmak zorunda değilsiniz), font dosyalarını barındırabileceğiniz alandır.
  • Models : Model dosyalarının barındırıldığı klasördür.
  • Scripts : Javascript tarzı script dosyalarını barındırabileceğiniz alandır.
  • Views : View dosyalarının barındırıldığı klasördür.​
  • favicon.ico : Tarayıcının üst kısmında ve favori siteler kısmında görünen ikondur.
  • Global.asax : Sitenin genelinde yapılan işlemlerin kontrol edilmesini sağlar. Örneğin bir üye oturum açtığında, sunucu ilk açıldığında, oturum kapatıldığında gibi aksiyonlar esnasında, yapılması gerekenleri bu sınıf içerisinde kontrol edebiliriz.
  • packages.config : Proje de kurulu olan frameworklerin kayıtlı olduğu yerdir. Buraya genelde Nuget Paket Yöneticisi vasıtasıyla paketler kurulabilir.
  • Project_Readme.html : Örnek proje hakkında Microsoft’un hazırladığı bilgilendirme sayfasıdır.
  • Startup.cs : Daha önceden App_Start klasörünün altında bulunan bu dosya, Mvc 5 sürümü ile birlikte ana dizine alınmış durumdadır.
  • Web.config : Proje ile ilgili tüm merkezi ayarların saklandığı yerdir. E-posta hesap bilgileri, Cookie süreleri, Sql bağlantı bilgileri vb. tüm bilgiler bu alanda kaydedilebilir ve düzenlenebilir.

MVC Filters

MVC tasarım kalıbı ile birlikte bir taşla 2 kuş değil, 1 taşla 10 kuş vurmaya alıştık bu alışkanlığı en bariz şekilde hissetiren özelliklerin başında ise MVC’nin Filters özelliği geliyor.

Filters’lar adından da anlaşılacağı gibi web uygulamanıza gelen her bir isteğin arasına girip belirli evrelerinde ihtiyacınıza göre işlemler yapabileceğiniz mekanizmalardan oluşuyor. Bu mekanizmalar bazen sayfanın çalışma zamanının alınması, bazen de güvenliği sağlayan kontroller olabiliyor. İsterseniz tüm uygulamanız için, isterseniz de belirli istekler geldiğinde filitre uygulayabiliyorsunuz.

Filters’lar method’un başına birer özellik (Attiribute) olarak kullanılmaktadır ve ActionFilterAttribute sınıfından türetilmesi gerekmektedir. Daha sonrada ihtiyacımız olan olayları override edip rahatlıkla kullanabilmektesiniz.
Yazı bir işe yarasındiye basit bir senaryo belirleyip ona göre hareket ettim, bakalım filters’lar ile neler yapabiliyoruz.

Belirlediğim gaddar senaryoya göre web uygulamama internet explorer ile girişi yasaklamak istiyorum ve bunun içinde en iyi yol Global Filters’i kullanmak olduğunu biliyorum ve aşağıdaki gibi kendi filter’imi  oluşturuyorum.

using System.Web.Mvc;

namespace MvcApplication1.Models
{
public class CheckBrowserAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
}

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var userAgent = filterContext.HttpContext.Request.ServerVariables["HTTP_USER_AGENT"];
if (userAgent.IndexOf("MSIE") != -1)
filterContext.Result = new ContentResult()
{ Content = "<script>alert('YASAK! FireFox veya Chrome kullanın.');</script>" };

base.OnActionExecuting(filterContext);
}

public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
}

public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
}
}
}

Gördüğünüz gibi ActionFilterAttribute sınıfından miras aldığım 4 adet olay var. Bu olayları uzun,uzun anlatmaya gerek yok sanırım isimlerinden hangi sıra ile çalıştığı belli. Biz Controller’ımızın içindeki kod çalışmaya başlamadan önce browser kontrolünü yapacağımız için OnActionExecuting olayına kodumuzu ekleyeceğiz.

using System.Web.Mvc;

namespace MvcApplication1.Models
{
public class CheckBrowserAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
}

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var userAgent = filterContext.HttpContext.Request.ServerVariables["HTTP_USER_AGENT"];
if (userAgent.IndexOf("MSIE") != -1)
filterContext.Result = new ContentResult()
{ Content = "<script>alert('YASAK! FireFox veya Chrome kullanın.');</script>" };

base.OnActionExecuting(filterContext);
}

public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
}

public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
}
}
}

OnActionExecuting olayında ziyaretçinin user-agent bilgisinden browser’ının ne marka olduğunu öğrendik ve içinde “MSIE” stringi geçiyorsa ContentResult’u kullanarak bir JavaScript uyarısı çıkarttık. Ziyaretçinin user-agent değerinin içinde aradığımız string’i bulamasaydık Context Resul normal bir ViewActionResult() olarak gelecekti buda bize sayfayı doğru görmemizi sağlayacaktı.

Şimdi bunu filitrenin tüm Action’larda çalışmasını sağlamak için MVC uygulamamızın Global ActionFilter koleksiyonuna eklememiz gerekli. Bununda Global.asax dosyasından tek bir satır ile yapabiliyoruz. Global.asax dosyasını açtıktan sonra ilgili satırı aşağıdaki gibi ekleyin.

using System.Web.Mvc;
using System.Web.Routing;
using MvcApplication1.Models;

namespace MvcApplication1
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new CheckBrowserAttribute()); // <= Filitremiz
}

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}
}

Bu işlemden sonra artık web uygulamamıza internet explorer’dan girilemeyecektir.

Gördüğünüz gibi hayatı kolaylaştıran bir özellik. Filitrelerin başka bir kullanım şeklide Action’a özel bir Attribute şeklindedir. Bunada bir senaryo üretip örnekleyelim.

Senaryoyu yine kullanıcı üzerinden geliştirmeye devam edip ziyaretçinin oturum açıp, açamadığını kontrol eden bir filter yazacağız. Senaryomuza çok ugun çünkü web uygulamalarında herkesin görebileceği ve sadece üyelerin görebileceği yerler olmakta.

using System.Web.Mvc;

namespace MvcApplication1.Models
{
public class LoginRequiredAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Session["isLogIn"] == null)
filterContext.Result = new RedirectResult("~/Home/Login");

base.OnActionExecuting(filterContext);
}
}
}

Burda görüldüğü gibi basit bir Session kotrolünden başka bir şey yapmıyoruz, esas olay Action’a eklediğim Attribute ile gerçekleşiyor.

[LoginRequired]
public ActionResult Users()
{
return View();
}

Action’ın üzerine LoginRequired filitremizi koyduktan sonra bu action’a yapılan her istekte session kontrol edilecek, yoksa ziyaretçinin giriş yapması istenecektir. Ek olarak dikkat ederseniz .Net’te örf ve adetler gereği ile LoginRequiredAttribute yerine sadece LoginRequired yazabiliyoruz. tıpki Interface’lerin I ile başlaması geleneği gibi.

Alındır, http://blog.oguzhan.info/?p=36

MVC’de Layout’a VeriTaşıma-Aktarma

MVC’de en çok sorulan soru muhtemeldir ki “Mvc’de usercontrol’lere nasıl data taşırım?” sorusudur. Bu makalede bununla ilgili olması gereken iyi bir çözüm sunacağım. Önce kendimize bir senaryo çizelim bir e-ticaret sitemiz var ve ürün kategorilerini tüm sayfalarda listelemek istiyorsunuz. Bu durumda ne yaparız ya kategoriler diye bir usercontrol yaratıp onu masterpage’imizin içine koyarız yada direk olarak masterpage’de datayı listeleriz. Sanırım UserControl yaratıp MasterPage’de onu çağırmak daha temiz bir kod düzeni sağlayacaktır bizlere. Bildiğiniz gibi datalarımızı taşıyan ve işleyen katmanımız MVC’de Controller katmanıdır. Biz şimdi öyle bir sınıf yazacağız ki sitedeki tüm controller’den bize kategoriler data’sı otomatik olarak gelicek. Burada inheritance’dan faydalanacağız.

image

Fark edebileceğiniz gibi yukarıda yazılı olan sınıf bir abstract sınıftır ve Controller sınıfından türemiştir. Yani herhangi bir Controller’dan tek farkı abstract olarak tanımlanmasıdır. Şimdi işimiz artık bitti diyebiliriz bundan sonra yapacağımız tek şey bunun dışında oluşturacağınız controller’ları Controller sınıfından değil de şimdi yarattığımız abstract sınıf olan GenelController’dan türeteceğiz. Böylece her Controller’da otomatik olarak ViewData[“kategoriler”] nesnesi oluşacak. Artık istediğiniz sayfada ViewData[“kategoriler”] diyerek ürün kategorilerinize sahip olabilirsiniz. İyi çalışmalar, umarım yardımcı olabilmişimdir.