eray aydoğdu

jQuery and ASP.NET MVC fanatic.

Asp.net MVC ‘nin Jquery isteklerinde Session Timeout durumu

Şuan geliştirmekte olduğumuz projede get/post işlerinin çok büyük bir bölümü jquery ile yapılıyor. Bu senaryoda şöyle bir sorun ile karşılaştık. Session Timeout a düştüğünde jquery istekleri 503 Server error döndürüyor. Timeout durumunu handle edebilmemiz için şöyle bir yol izleyebiliriz:

Session expire durumunu kontrol edecek methodumuz:

public static bool IsSessionExpired(this HttpSessionStateBase session)
{
    if (session == null || !session.IsNewSession)
    {
        return false;
    }

    string sessionCookie = HttpContext.Current.Request.Headers["Cookie"];
    return sessionCookie != null && sessionCookie.Contains("ASP.NET_SessionId");
}

Uygulamada istediğimiz yerde kullanabilmemiz için yada direkt olarak BaseController da kullanabilmemiz için Attribute oluşturalım.


[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class SessionExpireAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            HttpContext ctx = HttpContext.Current;

            if (ctx.Session != null)
            {
                if (filterContext.HttpContext.Session.IsSessionExpired())
                {
                    var viewData = filterContext.Controller.ViewData;
                    viewData.Model = username;
                    filterContext.HttpContext.Response.StatusCode = 504;
                    filterContext.Result = new ViewResult { ViewName = "SessionTimeout", ViewData = viewData };
                }
            }
        }

    }

Bundan sonra Jquery isteklerinde hata status code unun 504 olup olmadığını kontrol edelim.


   $("#NewTemplate").live("click", function () {
          if (confirmNavigation($(this))) {
              $("#selectedTemplateId").val(0);
              $.ajax({
                  type: "GET",
                  url: Urls.NewTemplate,
                  async: false,
                  cache: false,
                  success: function (cb) {
                      if (!cb) {
                          alert("Hata oluştu!");
                      }
                      else {
                          uiChanges = true;
                          $("#divTemplate").html(cb);
                      }
                  },
                  error: function (xhr, textStatus, errorThrown) {
                      redirectOnSessionTimeout(xhr.status);
                  }

              });
          }
      });

      function loadAuditTableGrid(name) {
        $("#auditTableGrid").load(
            Urls.AuditTable,
            { auditTableName: name },
            function (response, status, xhr) { redirectOnSessionTimeout(xhr.status); });
       }

      //$.getJSON
      reqJSON(Urls.CheckForActiveState, { id: selectedId},
             function (result) {
               if (!result.success)
                  $("#Message").show();
               else
                  $("#Message").hide();

                  }, function (xhr, textStatus, errorThrown) {
                            redirectOnSessionTimeout(xhr.status);
       });

      function reqJSON(url, params, success, error) {
        var CallParams = {};
        CallParams.type = params.Method || "POST";
        CallParams.url = url;
        CallParams.processData = true;
        CallParams.data = params;
        CallParams.dataType = "json";
        CallParams.success = success;
        if (error) {
            CallParams.error = error;
        }
        $.ajax(CallParams);
      }

      function redirectOnSessionTimeout(status) {
        if (status == "504") {
            location.href = Urls.SessionTimeout;
        }
     }

RenderAction ile RenderPartial Arasındaki Fark

Asp.net MVC ‘ye çok hakim olmayanların çoğu zaman hangisini kullanması gerektiğine karar veremeyen ve ikisininde aynı işi yaptığını düşünen kişiler için kısaca aralarındaki farktan bahsedelim.Aslında RenderAction ile RenderPartial arasında büyük bir fark var.Aslında RenderAction standart mvc Action ı gibi çalışır. İstediğimiz controller da iken istediğimiz controller daki Action ı çalıştırıp sonucu döndürür. RenderPartial ise aynı controller daki bir VIEW i render eder.

RenderPartial özellikle bir Model belirtilmemişse view ile aynı Model’e sahiptir. RenderAction ise çok daha komplekstir. Kendi actionı ile ayrı bir Model’i olabilir, database’e bağlanabilir vs.

Bir widget’ınız var ve seçim yapamıyorsanız şöyle düşünün. Eğer kompleks işlemler yapacaksanız (database’e bağlanmak, veriler çekmek , datalarla işlemler yapmak vs vs) elbetteki RenderAction kullanmalısınız. Çok daha sade bir widget ise RenderPartial kullanabilirsiniz.

Örnek vererek açıklayayım. Haberler nesneleriyle iligili işlemleri yaptığım bir News controller ım var. Ana sayfada en son haberleri gösteren bir widget yapmak istiyorum. LastNews isimli bir Action oluşturup RenderAction kullanmam en doğru ve pratik bir seçim olacaktır.

Asp.Net MVC ve Jquery Mobile ile Mobil Uygulama

Akıllı telefonlar ve tabletler gibi mobil platformların kabiliyetlerinin güçlenmesiyle uygulama geliştiriciler için her geçen gün daha önemli hale gelmeye başladı.  JQuery Mobile mobil platformlarda kolayca uygulama geliştirmemizi sağlayan bir framework. Asp.Net MVC 2 (HTML 5) ve Jquery Mobile kullanarak çok basit bir mobil uygulama yapalım.

Visual Stduio 2010 yeni bir proje oluşturduğumuz default olarak XHTML 1.0 dökümanı olarak oluşturur. Bunun yerine default template olarak HTML5 dökümanı oluşturmasını sağlayabilirsiniz. Google da biraz aramayla halledebilirsiniz. Ben şimdi manuel olarak HTML5 e çevireceğim.

Not: Uygulamayı MVC 2 de yapacağız ancak MVC 3 te de çalışacaktır. Ayrıca şuan JQuery Mobile Alpha 2 release ini kullanıyoruz. İleride bu framework oturduğunda bazı şeyler değişebilir.

Yeni bir Visual Studio 2010 projesi oluşturalım (ASP.NET MVC 2 Empty Web Application)

Views\Shared klasörüne ViewMasterPageMVCMobile.master adında bir Master Page ekleyelim.

Controllers klasörüne de HomeController ımızı açalım. Açılan Controller ‘ın içinde gelen Index Action’ına View ekleyelim. Ancak master page ini ViewMasterPageMVCMobile.master seçmeyi unutmayalım.

ViewMasterPageMVCMobile.master sayfanızı aşağıdaki kodlarla değiştirin.

<!DOCTYPE html>
<html lang="en-us" >
<head runat="server">
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.css" />
 <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
 <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.js"></script>
</head>
<body>
 <div data-role="page">
   <div data-role="header">
    <h1><asp:ContentPlaceHolder ID="PageTitleContent" runat="server" /></h1>
   </div>
   <div data-role="content">
     <asp:ContentPlaceHolder ID="MainContent" runat="server" />
   </div>
   <div data-role="footer">
     Footer
   </div>
 </div>
</body>
</html>

Jquery, Jquery Mobile ve CSS kütüphanelerini Jquery CDN sinden çağırarak kullandım ancak isterseniz indirip projenizin içinden de çağırabilirsiniz.

Döküman dan Jquery Mobile framework ünün sayfa yapısı hakkında daha geniş bilgiye ulaşabilirsiniz.

Şimdi Index view imizi oluşturalım aşağıdaki gibi kolay bir kod bloğu ekleyelim.


<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/ViewMasterPageMVCMobile.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
MVC Mobile
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="PageTitleContent" runat="server">
Page Title Goes Here
</asp:Content>

<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
This is the main content
</asp:Content>

Şimdi projeyi çalıştırabiliriz. Yalnız proje IE7 de çalışmıyor. IE8 yada IE9 da denemedim. Chrome, Firefox ve Safari de gayet güzel ekran boyutunu küçülterek deneyebilir yada mobil platformdan bağlanırsanız, Jquery Mobile ın her telefon için farklı çalışarak sorunsuz entegre olabildiğini göreceksiniz.

MVC 3 Custom Helper Yaratmak

HTML helper lar viewlerimizi karışık programatik kodlardan kurtarark temiz ve sade bir görünüm kazanmasını sağlar. System.Web.Mvc.HtmlHelper class’ında birçok HTML helper bulunmakta ancak biz kolayca kendi helper ımızı yaratacağız. MVC 1 kullanırken extension methodlar kullanarak kendi helper’larımızı oluşturabiliyorduk. Ancak şimdi Razor view engine ‘nin yeni özelliği olan @helper keyword ‘ünü kullanarak bu işlemi ne kadar kolay yapacağımızı göreceğiz.

Extension Method helpers

Asp.Net MVC ‘nin önceki sürümlerinde HtmlHelper class ına extension methodlar yazmamıza izin veriyordu. MVC 3 te de bunu yapabiliyoruz. Helper lar sadece string döndüren birer methodlardır, bu yüzden çok basitler. MVC Music Store örneğinden yola çıkalım. Uzunluğunu verdiğimiz string değeri kesen bir truncate helperı yapalım.

Extension method un static class olması gerekiyor ve genellikle proje yapısından farklı bir klasöre ayırmakta fayda var.

Kod standart extension method mantığında. İlk parametre olan this keyword u bunun bir HtmlHelper uzatması olduğunu belirtiyor. Diğerleri basit string döndürmek için. Method bir string ve uzunluk alıyor. Eğer string uzunluktan fazla ise uzunluğu kırpıp string i geri döndürüyor.

using System.Web.Mvc;
namespace MvcMusicStore.Helpers
{
public static class HtmlHelpers
{
public static string Truncate(this HtmlHelper helper, string input, int length)
{
if (input.Length <= length)
{
return input;
}
else
{
return input.Substring(0, length) + "...";
}
}
}
}

Not: Uzatmasını yaptığımız HtmlHelper System.Web.WebPages ta değil System.Web.Mvc de tanımlandığından emin olalım. Bu ifade önemli.

Yeni yarattığımız helper namespace'sini ister web.config dosyasında tanımlayarak tüm viewlerde kullanabilirsiniz, isterseniz de razor view engine in özelliği olan @using keyword ü ile sadece o sayfada tanımlayabilirsiniz.

Şimdi yazdıklarımızı deneleyim default olarak gelen index sayfasında deneyeceğiz.

@{
ViewBag.Title = "Home Page";
}
@using RazorHelpers.Helpers
<h2>@Html.Truncate(ViewBag.Message as string, 8)</h2>

Dikkat edilecek bir noktada burada ViewBag.Message ı string olarak cast etmeliyiz. Aksi takdirde sayfa render  olurken compiler hatası alabiliriz.

Alternatif olarak istersek web.config dosyasındaki pages>namespace lere eklersek @using keyword ü ile tanımlamadan kullanabiliriz.

Inline Razor Helper

Razor da inline helper yapmak için sadece @helper bloğu açmak yeterli.

@{
ViewBag.Title = "Home Page";
}
@helper TruncateString(string input, int length)
{
if (input.Length <= length) {
@input
} else {
@input.Substring(0, length)<text>...</text>
}
}
<h2>@Truncate(ViewBag.Message, 8)</h2>

Kod çok basit ancak bir kaç farklılık var,

  • Razor syntax ına göre method adıyla dönüş tipi bitişik yazılıyor.
  • this HtmlHelper gibi işlere girmemize gerek yok çünkü bir extension method değil.
  • Input u string e çevirmek zorunda değiliz Razor engine bunu ayırt edebiliyor.
  • Extension method olmadığı için diren @Truncate() olarak kullanabiliyoruz, @Html.Truncate() yazmamıza gerek yok.

İhtiyaçlarınıza göre helper lar yazarak, geliştirerek kendine ait güçlü kolay ve kullanışlı bir helper kütüphanesi oluşturabilirsiniz.

 

WordPress Son Yazıları Asp.NET MVC ‘de Göstermek

Bir önceki yazımızda Asp.net MVC ile WordPress i nasıl birlikte çalıştırmayı öğrenmiştik. Bu yazımızda da WordPress e eklenen son yazıları Asp.net MVC uygulamasına nasıl çekeceğimizi göreceğiz. Aslında bu birlikte çalışan değil tüm wordpress sitelerden nasıl çekeceğimizi gösteren bir örnek olacak. Çünkü Son Yazılar kısmını ilgili wordpress in Databaseinden değil RSS ‘inden parse ederek çekeceğiz. Dolayısıyla altyapısı wordpress ve RSS yayını yapan her siteden çekebiliriz. Çok fazla uzatmadan kodlara geçelim.

Projemize;

using System.Xml;
using System.ServiceModel.Syndication;

namespacelerini çağıralım.

BlogBox.ascx adında bir ViewUserController oluşturalım ve ardından aşağıdaki Action kodlarını yazalım.

public ViewResult BlogBox()
{
var reader = XmlReader.Create(“http://erayaydogdu.com/feed“);
var feed = SyndicationFeed.Load<SyndicationFeed>(reader);
return View(feed);
}

XML i oluşturup SyndicationFeed.Load() methoduyla feed değişkenine atayıp feed i View in Modeline gönderiyoruz.

Şimdi View i oluşturalım.

<%@ Control Language=”C#” Inherits=”System.Web.Mvc.ViewUserControl<System.ServiceModel.Syndication.SyndicationFeed>” %>
<span>Blog’tan</span>
<ul>
<%foreach (var item in Model.Items.Take(5))
{%>
<li>
<a href=”<%=item.Links.First().Uri.AbsoluteUri%>><%=item.Title.Text %></a>
</li>
<%} %>
</ul>

View de ilk 5 Tanesini <li> lere yazdırdık. Property lerini inceleyerek daha detaylı veriler elde edebiliriz. Biraz araştırarak kendine göre geliştirebilirsiniz.

Eski Yazılar »