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;
        }
     }

Gözüküp Saklanabilir Pop-up

İşlerin yoğunluğundan ikinci plana attığım blog yazılarına nihayet uzun bi aradan sonra dönüş yapıyorum. Bundan sonra işlerim ne kadar yoğun olursa olsun blog yazılarına zaman ayırmaya çalışacağım. Hızlı ve kısa blog yazıları yolda demek oluyor bu…

Yakın zamanda bir projede ihtiyacım olan bir jquery plug-ini göstereceğim. Adı Meerkat sitede tanıtılandan çok enteresanfarklı bir yerde kullandım ancak ihtiyacınıza çok farklı durumdalarda işe yarayabilir.

Sitesinde de inceleyebileceğiniz gibi ekranın 4 tarafında bir çeşit pop-up açabiliyor, en önemlisi bunu yanlızca tek sefer gösterebiliyorsunuz (Browser session ı sonlanana kadar).

Kullanımına şu şekilde göz atalım:

Öncelikle jquery kütüphanesini ve tabi merkaat ı çağırıyoruz.

<script src="jquery.min.js" type="text/javascript"></script>
<script src="jquery.meerkat.js" type="text/javascript"></script>

Merkaat ın çalışması için gerekli HTML kodlarımızı da aşağıdaki gibi ayarlıyoruz. Gerekli olan html elemanları body etiketinin kapanmasından hemen öncesine classı merkaat olan bir div yerleştiriyoruz.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>Meerkat: A jQuery Plugin (Basic Demo)</title>
  <script src="jquery.min.js" type="text/javascript"></script>
  <script src="jquery.meerkat.js" type="text/javascript"></script>
  <script type="text/javascript">
     $(document).ready(function(){
        //Meerkat
     });
  </script>
</head>
<body>
  <div id="wrapper">
      Web sayfa içeriği burada
  </div>
  <div>
      Meerkat içeriği burada
  </div>
</body>
</html>

Şimdi merkaat kodlarını document ready ye ekleyelim.

$('.meerkat').meerkat({
     background: 'url(images/meerkat-bot-bg.png) repeat-x left top',
     height: '120px',
     width: '100%',
     position: 'bottom',
     close: '.close-meerkat',
     dontShowAgain: '.dont-show',
     animationIn: 'slide',
     animationSpeed: 500
});

Dökümantasyon dosyası ingilizce ancak bilmesenizde belli başlı ayarlar için yardımcı olacaktır. Onun dışında takıldığınız veya sormak istedikleriniz için yorum yazarsanız yardımcı olmaya çalışırım.

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.

Jquery JqGrid’ten Excel’e veri Aktarma

Bu makalemizde Jquery kütüphanesinin JqGrid plug-in ni kullanarak verileri göstermeyi ve bu verileri excel e aktarmayı göreceğiz. JqGrid size verilerinizi sıralama, sayfalama, arama gibi işlemleri kolayca yapmanızı sağlıyor.

Uygulamamızı Asp.Net MVC 1.0 da geliştireceğiz. Öncelikle JQuery ve JGrid kütüphanelerini indirmeliyiz.

JqGrid i sayfamıza yerleştirelim

Ürünleri database’den çekmeden önce sayfamızdan gerekli script lere referans verdiğimizden emin olmalıyız. Master Page te bütün CSS ve JS leri çağırmalıyız.

 <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />  
    <link href="../../Content/ui.jqgrid.css" rel="stylesheet" type="text/css" />  
    <script src="../Scripts/jquery-1.3.2.js" type="text/javascript"></script>  
    <script src="../Scripts/jquery.jqGrid.js" type="text/javascript"></script>  
    <script src="../../Scripts/Site.js" type="text/javascript"></script>  

Bu işlemleri tamamladıktan sonra örnek olarak Northwind database “Products” table ı kullanarak repository i oluşturalım.

 public class ProductRepository : IProductRepository
    {
        public List<Product> GetAll()
        {
            using(var db = new NorthwindDataContext())
            {
                return (from p in db.Products
                       select p).ToList();
            }
        }
    }

loadProduct fonksiyonu View yani sayfamız load olduğunda verileri çağıracak.

<script language="javascript" type="text/javascript">

    // load the products
    loadProducts(); 

</script>  

<% using (Html.BeginForm(new { Action = "ExportToExcel" }))
 {%>

<table id="list"></table>

<input type="submit" value="Excel e aktar" />

<%

 }%>

Şimdi loadProduct methodumuza bakalım.

function loadProducts()
{
    jQuery(document).ready(function() {
        jQuery("#list").jqGrid({
            url: '/Home/GetProducts/',
            datatype: 'json',
            mtype: 'GET',
            colNames: ['Id', 'Name', 'QuantityPerUnit',"UnitPrice"],
            colModel: [
          { name: 'Id', index: 'Id', width: 40, align: 'left' },
          { name: 'Name', index: 'Name', width: 40, align: 'left' },
          { name: 'QuantityPerUnit', index: 'QuantityPerUnit', width: 200, align: 'left' },
          { name: 'UnitPrice', index: 'UnitPrice', width: 200, align: 'left' }],
            rowNum: 10,
            rowList: [5, 10, 20, 50],
            sortname: 'Id',
            sortorder: "desc",
            viewrecords: true,
            caption: 'My first grid'
        });
    });
}

Şimdi de Controller ımızdaki kodu hazırlayalım.

 public ActionResult GetProducts(string sidx, string sord, int page, int rows)
        {
  var products = _productRepository.GetAll();

            var totalPages = 1; // we'll implement later
            var totalRecords = 3; // implement later

            var jsonData = new
                               {
                                   total = totalPages,
                                   page = page,
                                   records = totalRecords,
                                   rows = (from p in products
                                           select new
                                                      {
                                                          id = p.ProductID,
                                                          cell = new string[]
                                                                     {
                                                                         p.ProductID.ToString(), p.ProductName,
                                                                         p.ProductName
                                                                     }
                                                      }).ToArray()
                               };

            return Json(jsonData);
}

_productRepository.GetAll() methodu Product Tablosundaki verileri çekmemizi sağladı. Son olarak JqGrid için gerekli olan properties leri bulunduran jsonData adındaki Anonymous type değişkenimizi oluşturduk.

Projemizi çalıştırdığımızda aşağıdaki görüntüyü elde edeceğiz.

ToJsonForjqGrid<T> Extension Method u Oluşturmak:

ToJsonForjqGrid<T> extension ı jqGrid in desteklediği List<T> collection a çevirmek zorundayız.
  public static object ToJsonForjqGrid<T>(this List<T> list,string primaryKey,string[] columnNames) where T : new()
        {
            if(list.Count() == 0)
                throw new ArgumentException("List does not contain any items!");

            var jsonData = new
                               {

                                   rows = (from p in list
                                          select new
                                        {
                                            id = p.GetPropertyValue(primaryKey),
                                            cell = p.GetPropertyValues(columnNames)       
                                        }).ToArray()                               

                               };

            return jsonData; 
        }

ToJsonForJqGrid<T> iki parametre alıyor. Birincisi primarykey yani row daki property nin id’si. İkincisi ise columnNames[] griddeki kolonların isimleri.

Şimdi GetProducts ı ToJsonForJqGrid i kullanarak değiştirelim.

 public ActionResult GetProducts(string sidx, string sord, int page, int rows)
        {

            var jsonData = _productRepository.GetAll().ToJsonForjqGrid("ProductID", new[] { "ProductID", "ProductName" });
            return Json(jsonData);

        }

Eğer daha fazla kolon göstermek istersek columnName e bir kaç alan daha eklememiz yeterli.

...ToJsonForjqGrid("ProductID", new[] { "ProductID", "ProductName", "QuantityPerUnit","UnitPrice" });

Grid i Excele Aktarma

Excel e Aktar butonu tıklandığında ExportToExcel action ı tetiklenecek.

 public ActionResult ExportToExcel()
        {
            var products = _productRepository.GetAll();

            var grid = new GridView();
            grid.DataSource = from p in products
                              select new
                                         {
                                             ProductName = p.ProductName,
                                             SomeProductId = p.ProductID
                                         };
            grid.DataBind();

            Response.ClearContent();
            Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");

            Response.ContentType = "application/excel";

            StringWriter sw = new StringWriter();

            HtmlTextWriter htw = new HtmlTextWriter(sw);

            grid.RenderControl(htw);

            Response.Write(sw.ToString());

            Response.End();

            return View("Index");
        }

Herkese iyi çalışmalar..

JQuery İle Slider Yapımı

JQuery ile tıklandığında kayan yazı yada kayan resim yapmamızı sağlayan basit ve geliştirmeye açık bir örnek.

jquery-1.3.2.js (117,93 kb)
jquery.easing.1.3.js (7,91 kb)
Bu iki dosyayı aşağıdaki kodlarla ilgili sayfamıza çağırıyoruz:

(more…)

Eski Yazılar »