Asp.Net MVC - Arama Motoru Dostu linkler için Custom Link Senaryosu

By Burak TUNGUT - 26.1.2013 - 5 Yorum - Kategori Asp.Net MVC

Öncelikle herkese merhabalar :) Yaklaşık 2 aydır aşırı tempolu geçen bir dönem içerisindeydim. Neyse ki dersler, projeler derken sonun da hepsini atlattım. Tabi tatil dönemini yarılamış olmamda beni bir hayli üzüyor. Bazen sormuyor değilim kendime zaman ne çabuk geçti diye J

Neyse artık yavaş yavaş  bugünkü konumuza gelelim.

Uzun zamandan beri Asp.Net MVC hakkında bir yazı dizine başlamak istiyordum. Bu başlangıcı aslında geçtiğimiz haftalarda Asp.Net MVC Giriş adlı webiner ile yaptım. Bu günkü konumuz ise View tarafında Link işlemlerinin nasıl yapılacağı olacak.  Bunun yanında Helper sınıflar için extension metotlar yazarak kendimize özel (Custom) Link’ler yaratılmasını sağlayacağız.
Tüm bunları yaparken örneğin teoride kalmaması için biraz Routing ayarlaması ile de uğraşacağız tabi ki :)

Senaryomuzu Tanıyalım

Bugün yapacağımız örnekleri bir Haber sayfası senaryosu üzerinden yapacağız. Bunun için öncelikle her ne kadar var olmasa da News adında bir veri tabanı tablomuzun olduğunu düşünelim ve bu tabloyu bir entity class niteliğinde modelleyelim.

Model klasörümüz altında bir adet sınıf oluşturalım ve modelleme işlemimizi aşağıdaki kodlar yardımıyla gerçekleştirelim;

public class News
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
    }

Deneme amaçlı olarak kullanacağımız ve elimiz ile birkaç haber kaydı ekleyeceğimiz için sade bir model oluşturamaya özen gösterdim.

Haber Depomuza Kayıtlarımızı Ekleyelim

Az önce bahsettiğim gibi az da olsa birkaç kayıt uygulamamızı çalışır hale getirmek için yeterli olacaktır. Bunun için News sınıfı içerisinde Repository adında bir property tanımlayalım. Bu property bizlere ekleyeceğimiz 10 adet haber kaydını sunsun. Bu durumda tipimiz bir collection olacaktır. Fakat her ulaştığımızda tekrar tekrar bu işlemi yapmaması için küçük bir encapsulation uygulamakta fayda var.

Dediklerimizi şöyle toparlayalım o zaman. Biri public diğeri private olan iki adet static property tanımlayalım ve haber kayıtlarını ilk çalışma anında yükleyecek bootstrap tadında bir metot yazalım.

O zaman News sınıfımızın içerisine aşağıdaki kod parçalarını da ekleyelim;

private static IList<News> _Repository = null;
        public static IList<News> Repository
        {
            get
            {
                if (_Repository == null)
                    _Repository = GetNews();
                return _Repository;
            }
        }

        private static IList<News> GetNews()
        {
            var result = new List<News>();
            for (int i = 1; i <= 10; i++)
            {
                result.Add(new News
                {
                    Id=i,
                    Title=string.Format("{0}. Haberin Başlığı",i),
                    Content = string.Format("{0}. Haberin İçerik Detayı")
                });
            }
            return result;
        }

News Controller sınıfının eklenmesi

Şu ana kadar MVC patterinin Model kısmını tamamladık. Sıra Controller katmanında. Bunun için controller klasörümüz altında bir adet controller sınıf ekleyelim. Adını da NewsController yapalım.

Visual Studio sağolsun bizler için Index actionunu ekledi J Biz de bu Action’ın bağlanacağı View’de eklenmiş olan 10 adet haberimizin başlıklarını listeleyelim ve bu başlıklara birer link verelim. Linklere tıklanması halinde başka bir View çalışsın ve haberin detayı gösterilsin.

Öncelikle Index actionunda bağlanacak olan View’e model olarak elimizde hazır olan haber kayıtlarını sunalım. Bu durumda kodlarımız aşağıdaki gibi olacaktır;

public ActionResult Index()
        {
            var model = News.Repository;
            return View(model);
        }

Hiç View tarafının kodlamasına geçmeden bir de detay sayfası için bir ActionResult ekleyelim. Hiç şüphesiz bu metot parametre olarak Id alacaktır ve aldığı Id ile eşleşen kaydı model olarak bağlanacağı View’e sunacaktır.

Detail adlı actionumuz da aşağıdaki gibi olacaktır. Bu arada Visual Studio’nun bir kısayolundan bahsetmek istiyorum. Bir ActionResult eklemek istiyorsak kod kısmına “mvcaction” yazıp enter dememiz yeterli olacaktır :)

public ActionResult Detail(int Id)
        {
            var record = News.Repository.SingleOrDefault(q => q.Id == Id);
            return View(record);
        }

Index ve Detail View'leri

Sırasıyla MVC patternimizin önce Model kısmını sonrada Controller kısmını tamamladık. Şimdi ise presentation layer niteliği taşıyan View katmanında işlemlerimize devam edelim. Bu noktada öncelikle Index view’ini ekleyelim. Bunun için Index() kısmına sağ tıklayıp “Add View” demeniz, eklediğiniz View’e ulaşmanız içinde “Go To View” demeniz yeterli olacaktır.

Eklediğimiz View içerisinde kullanacağımız model hatırlarsanız News sınıfı içerisindeki Repository property’si idi. Bu da demektir ki View içerisinde model olarak IList<News> tipini kullanacağız.
View kodlarımız aşağıdaki gibidir;

@model IList<Makale.CustomLinkProject.Models.News>
@{
    ViewBag.Title = "Index";
}

<h2>Haber Listesi</h2>
@foreach (var item in Model)
{
    <a href="@Url.Action("Detail","News", new { @Id = item.Id})">@item.Title</a>
    <br />
}

Bir foreach döngüsü ile model tarafında gelen tüm veriyi ekrana aralarında birer satırlık boşluk olacak şekilde yazdırıyoruz.

Dikkat ederseniz link işlemi için UrlHelper sınıfı içerisinde ki Action metodunu kullandık. Bu metod 8 adet override’a sahiptir. Yaygın olarak sırasıyla Action, Controller, routeValues parametrelerini alan metodu kullanılır. İlk iki parametre adresleme işlemini yaparken routeValues kısmı object alan bir parametredir. Ve içerisine eklenilen her özellik linklendirme işleminde aslında Query String niteliği taşır. Fakat Id adını taşıyan ve integer veri tipindeki eklenecek özellikler Asp.Net MVC’nin kullandığı route yapısının gereği “Controller/Action/Id” şeklinde kullanılır.

Bu View ile şimdilik işimiz bitti.

Birde detay sayfamızı hazırlayalım. Bunun için Detail adlı viewimizin eklenmesini sağlayalım. Bu sayfamızın kodlarıda aşağıdaki gibi olacaktır;

@model Makale.CustomLinkProject.Models.News
@{
    ViewBag.Title = "Detail";
}

<h2>@Model.Id - @Model.Title</h2>
@Model.Content

Bu sayfamıza gelecek olan model hatırlarsanız bir News tipiydi. Bu nedenle model implementasyonu da News tipi üzerinden yapılacaktır. Şu anda projemiz kullanılmaya hazır gibi görünüyor. Dilerseniz projeyi debug edebilirsiniz fakat önce Route tarafında bir düzeltme yapmamız gerekmekte.  Projemizde HomeController bulunmadığı için ilk açılışta ufak bir hata ile karşılaşılacaktır. Bu nedenle default controller özelliğimizi News olarak değiştirmeliyiz.

Global.Asax dosyasını açalım ve RegisterRoutes kısmında ekli bulunan kısmı aşağıdaki gibi değiştirelim;

routes.MapRoute(

                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "News", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

Aynı zamanda yaratacağımız Custom Link içinde arama motoru dostu bir route tanımlayalım. Aklımdaki link tarzı şu şekilde; “Haber/haberin-basligi-2.html”

Böyle bir linki Route kurallarına göre eklemek için en önemli kısım Id kısmının yakalanması olacaktır. Ekleyeceğimiz route aşağıdaki gibi olacaktır. Bu kodu da RegisterRoutes metodu içerisine ekleyelim.

routes.MapRoute(null, "Haber/{seoText}-{id}", new { controller = "News", action = "Detail" });

Şu anda projemiz Run edilebilir. Dilerseniz projemizi debug ederek genel görünüşüne bir göz atınız.

Ana sayfada karşımıza çıkan haberler listesindeki linklere göz atarsanız “http://localhost:54575/News/Detail/6” şeklinde olduklarını göreceksinizdir. Bu link ile haberin başlığı ile ilgili herhangi bir bilgi verilmemektedir. Bu nedenle de arama motorunun pekte seveceği bir halde değil.

Artık Custom Link işlemimiz için extension metot yazmamızın zamanı geldi. Bunun için projeye bir adet sınıf ekleyelim. Adını LinkExtension koyalım. Extension sınıfların gerektirdiği static olma zorunluluğunu unutmayalım ve sınıfımızı static olarak tanımlayalım. Aynı zamanda View tarafında her seferinde using ile namespace import etmemek için eklediğimiz sınıfın namespace alanını “System.Web.Mvc” şeklinde yazalım.

Eklediğimiz sınıfın metot ile birlikte tam kodu aşağıdaki gibi olacaktır;

namespace System.Web.Mvc
{
    public static class LinkExtension
    {
        public static string NewsLink(this UrlHelper urlHelper, News entity)
        {
            string title = entity.Title;
            title = title.Replace(".", "-").Replace(" ","-");
            return string.Format("Haber/{0}-{1}.html", title, entity.Id);
        }
    }
}

Hatırlarsanız link işlemini UrlHelper sınıfı yardımıyla yapıyorduk. Bu nedenle extension metodumuzu bu sinif içerisinde listelenmesi için this anahtar kelimesinde bu sınıfı kullandık. Metod parametre olarakda News sınıfına ait bir nesne alıyor olacak şekilde tasarlandı. İç kısımda ise nokta ve boşluk simgelerini "-" olarak replace edilmesini sağladık ve tamda tasarladığımız link yapısın uygun bir yapı hazırlanmasını sağladık.

Şimdi Index adlı View'imize geri dönelim ve aşağıdaki kodları ekleyelim;

<h2>Yeni Haber Listesi</h2>
@foreach (var item in Model)
{
    <a href="@Url.NewsLink(item)">@item.Title</a>
    <br />
}

Yazdığımız metodun kullanımı son derece sade ve anlaşılır oldu. Ne bir Id değeriyle ne de bir controller ya da action ismi yazdık.

Hazırladığımız örnek sonunda tam anlamıyla bitti :) Artık projemizi son kez debug edebiliriz. Ana sayfaımızın genel görüntüsü ve link yapısı aşağıdaki gibi olacaktır;

MVC uygulama çıktısı

Projenin tam haline buradan ulaşabilirsiniz.

Bir sonraki makalemde görüşmek üzere, herkese esenlikler dilerim :)
Anlatımınız güzel, dikkatlice okudum ve uyguladım dedikleriniz ancak en son aşamada HTTP Hatası 404.0 - Not Found hatası alıyorum lütfen yardım edin bu konuda .asp.net mvc 4 kullanıyorum
Yorum Bırak

Facebook
Son Yorumlar