Javascript Kod Kapsamının Yapılandırılması

10 Haz

Web uygulamalarımız geliştikçe ve yazılan kod satırları arttıkça, kodun yönetimini kolaylaştırmak amacıyla kodun iyi yapılandırılmış olması önem kazanmaya başlar. Bu kural, yazılımcılar tarafından edinilen tecrübelerle ortaya konmuştur.

Bu yazımızda Javascript kodunun iyi yapılandırılmasıyla ilgili kurallardan bahsedeceğiz. Javascript ortamında değişkenler için kod kapsamını incelemeye çalışacağız.

Değişkenlerin Erişilebilirlik Alanları

Javascript, internet tarayıcılar tarafından yorumlanan bir dildir. Bu sebeple Client taraflı uygulamalar Javascript ile geliştirilebilir. Diğer popüler dillerden(C++, C#, Java v.b) bu yönüyle ayrılır. Kod yazım kuralları diğer programlama dillerine biraz benzerdir.

Javascript ortamında tanımlanan değişkenlere nereden ulaşılabileceğine geliştiriciler karar verir. Bir değişken, her yerden ulaşılacaksa global şekilde tanımlanabilir veya sadece bir fonksiyon içerisinde kullanılacaksa yerel bir şekilde de tanımlanabilir.

Yani iki yeni kuralımız ortaya çıkmış oldu.

  • Değişkenler bir fonksiyonun dışında tanımlanmışsa global olur.
  • Bir fonksiyon içerisinde tanımlanmışsa yerel olur ve o fonksiyon içinde her yerden(fonksiyon içindeki başka bir fonksiyondan bile) erişilebilir.

Örnek-1:

<script type="text/javascript">
     var name = "Bayram";

     function getUsername() {
          alert(name);
     }
</script>

Bu örnekte “name” değişkeni global olarak tanımlanmıştır. “name” değişkenine artık her yerden erişilebilir. Bu kodu bir *.js dosyasına tanımlayıp dosyayı gören her yerden “name” değişkenine erişebiliriz.

Örnek-2:

<script type="text/javascript">

    var name = "Bayram";

    function getUsername() {
       var name = "Undefined";
       alert(name);
    }
</script>

Bu örnekte tanımladığımız “getUsername” fonksiyonu çalıştırıldığında çıktı olarak “Undefined” şeklinde bir uyarı penceresi açılacaktır. “Bayram” diye uyarı vermeyecektir. getUsername fonksiyonu içinde yerel olarak tanımlanan “name” değişkeni global tanımlanan “name” değişkenini dikkate almamıştır.

Bu gibi durumlar, bazen istemediğimiz sonuçlara yol açabilir. Örneğin bir değişkenin unutularak tekrar değiştirilmesi sonucu yanlış bilgi alınması veya verilmesi gibi durumlar yaşanabilir. Çünkü global olarak tanımlanan değişkenlere web uygulamanızın her yerinden ulaşabilirsiniz.

Bu gibi çakışma sorunlarını bertaraf etmek için Javascript tarafında faydalanabileceğimiz birkaç yöntem mevcuttur. Bunlar:

  • Hemen cevap veren fonksiyonlar
  • Namespace (Ad alanları)

Hemen Cevap Veren Fonksiyonlar

Hemen cevap veren fonksiyonlar, tanımlandığı anda çalışan fonksiyonlardır. Yani bir yerde tanımlayıp başka yerde çalışan fonksiyonlar gibi değillerdir. Hemen cevap veren fonksiyonları anonim fonksiyon gibi iki parantez içine sarmalayarak hemen çalışır hale getirebiliriz.

Örnek:

<script type="text/javascript">

    (function () {
         var firstName = "Bayram";
         var lastName = "Üçüncü";
         var fullName = firstName + " " + lastName;
    })();

</script>

Tarayıcı bu fonksiyonu gördüğü anda çalıştırır. Fonksiyon içinde tanımlanan değişkenler global ad alanını (namespace) boşuna kirletmemiş olur. Mesela “firstName” değişkenine bu fonksiyon dışından erişmek mümkün değildir.

Namespace (Ad Alanlarının Kullanımı)

Global değişkenlerin çakışmalarını gidermek için kullanılan bir diğer yöntem ise namespace kullanımıdır. Javascript ortamında namespece içerisine değişkenler ve fonksiyonlar tanımlamak mümkündür.

Örnek:

<script type="text/javascript">

     var MyGlobalMapNamespace = {

          getMapName: function () {
                return "Nokia Maps";
          },
          getMapExtent: function () {
                return "411124, 552442, 4253211, 4011225";
          },
          gtMapLayers: function () {
                return 4;
          },
          owner: "Bayram Üçüncü"
     }
</script>

Bu örnekte tanımladığımız MyGlobalMapNamespace namespace içindeki üyelere şu şeklide erişmek mümkündür:

       MyGlobalMapNamespace.getMapExtent();
       MyGlobalMapNamespace.owner="Bayram";

Namespace içerisinde tanımlı üyelere bir gizlilik veya kapsülleme(encapsulation) yapmak söz konusu değildir. Namespace adı ile içerisindeki üyelere dışarıdan erişim mümkündür.

Bu şekilde Javascript ortamında değişkenlerle ilgili erişim bölgelerini yani kod kapsamına giren ve girmeyen bölgeleri incelemeye çalıştık. Global ve Yerel değişkenlerin hangi kapsamlarda kaldığını, değişken çakışmalarında alınacak önlemleri inceledik. Bir sonraki yazıda görüşmek dileğiyle.

ArcGIS Server Sitesi Yapısı Verisyon 10.1

5 Haz

Günümüzde son kullanıcı ürünleri ucuzlamaya başladıkça sunucu taraflı uygulamalar ve teknolojilerin fiyatları artmaya başladı. Sunucu gelişiminin son noktası bulut teknolojisi oldu. Bulut teknolojisinin iyice yaygınlaşmaya başladığı günümüzde firmalar sunucu mimarilerini bu gelişime uydurmak adına adımlar atılmaya başlandı. Artık sunucu tarafında çalışan sistemleri durdurmadan donanımsal tak çıkar işlemleri yapmak yani donanımların yetmediği noktalarda ölçekleme yapmak çok kolaylaştı. ArcGIS tarafı da bu gelişim karşısında duyarsız kalmayarak mimarisinde bazı değişikliklere gitti.

Bu yazımızda ArcGIS Server 10.1 ile birlikte SOM-SOC modeli yerine gelen Site yapısının iç yüzünü inceleyeceğiz. ArcGIS Server Site yapısı, birden fazla bilgisayar üzerine konuşlandırılabilecek şekilde ayarlanabilen bileşenlerden oluşur. Sitedeki her bir bileşen kaynak yönetiminde belirli bir role sahiptir.

ArcGIS Server sitesi bileşenleri şu şekilde özetlenebilir:

  • Web sunucusu: Web uygulamalarını barındırır, isteğe bağlı güvenlik seçenekleri sunar ve ArcGIS Server için yük dengeleme işlemlerini gerçekleştirir.
  • Web Adaptör: Gelen istekleri farklı CBS sunucu(GIS Server) bilgisayarlarına ileterek ArcGIS Server ile kurumsal web sunucunuzu bütünleştirir.
  • GIS Server(CBS sunucusu): CBS web hizmetleri için gelen istekleri karşılamak için çalışır. Bir CBS sunucusu harita çizimleri, görüntü hizmetleri, veritabanı senkronizasyonu, veri arama gibi birçok işlemi gerçekleştirir.
ArcGIS Server Site Mimarisi
ArcGIS Server Site Mimarisi

Bu resimde özetle ArcGIS Server sitesinin her bir bileşenin görevi ve bağlı olduğu bileşen gösterilmiştir.

Web Sunucusu (Server)

Web sunucusu web uygulamalarını barındırır, isteğe bağlı güvenlik seçenekleri sunar ve ArcGIS Server için yük dengeleme işlemlerini gerçekleştirir. ArcGIS  Server, IIS, WebSphere ve WebLogic gibi birçok web sunucusuyla uyumlu çalışır.

GIS server (CBS sunucusu) bileşeni servislerinizi HTTP protokolü üzerinden IIS gibi ayrı bir işlem gerektirmeden dışarı açabilir. Eğer web sunucusunun yerel güvenlik yapılandırmalarından(örneğin kullanıcı doğrulamasından)  faydalanmak isterseniz veya web uygulamalarınızı barındırmak isterseniz dağıtımınıza bir web sunucusu dahil edebilirsiniz.

Web Adaptor(Adaptör)

ArcGIS Web Adaptor, temelde web sunucunuzdan gelen istekleri CBS sunucularına(GIS Server) ileten bir web uygulamasıdır. Web Adaptörler siteye hangi bilgisayarların eklenip hangilerinin çıkarıldığını izler ve gelen trafiği bu bilgisayarlara uygun olarak dağıtır. Web Adaptör kullanarak siteniz için isimlendirme ve bağlantı(port) noktalarını yönetebilirsiniz. Örneğin varsayılan port 6080 ve site ismi “arcgis” iken Web Adaptör ile bunları değiştirebilirsiniz. Web Adaptörü sayesinde güvenlik için web sunucusunun yerel imkanlarını kullanabilir, ArcGIS Manager için veya ArcGIS Server yönetim dizinleri için dışarıdan gelen istekleri engelleyebilirsiniz.

Çalışma prensibi olarak bir servis isteği geldiğinde Web Adaptörü bu isteği GIS Server bilgisayarlarına iletir. Daha sonra GIS Server bilgisayarları, hangi bilgisayarın kullanılabilir olduğunu ve hangi bilgisayara işin atanacağı belirlemek için birbirleri ile iletişime geçerler. Eğer Web Adaptörü, GIS Server tarafının erişilemez durumda olduğunu belirlerse o sunucuya istek göndermeyi durdurur.

Web Adaptörü sitenizi sadece web ağ geçidi veya giriş noktası yapılandırmak için tek yöntem değildir. Diğer ağ geçidi teknolojileri de kullanılabilir. Fiziksel HTTP yük dengeleyiciler, ağ yönlendirici cihazları veya üçüncü parti bir yazılımla da bu işlemleri gerçekleştirmek mümkündür.

GIS Server (CBS sunucusu)

Sitenizde ArcGIS Server için kurulan bilgisayarları CBS sunucusu olarak düşünebilirsiniz. Haritalar, adresler, koordinatlar, coğrafi işlemler gibi web hizmetler için gelen istekler site içindeki ulaşılabilir durumdaki CBS sunucu bilgisayarına atanır. Daha sonra CBS sunucusu gelen isteğe uygun hizmeti hazırlayarak kullanıcıya cevap olarak gönderir. Aslında CBS sunucuları sitenizin iş merkezidir.

CBS sunucuları servisleri HTTP protokolü üzerinden dışarı sunarlar.

Birden fazla CBS sunucusu kullanarak sunuculardan birinin kesintiye uğradığı kriz durumlarında sitenizi kesintilere karşı koruyabilirsiniz. Bir CBS sunucusu devre dışı kaldığı durumda Web Adaptörü, gelen istekleri sitenizdeki diğer CBS sunucularına dağıtır. Bunlara ek olarak CBS sunucuları diğer CBS sunucularının eklenip çıkarıldığını algılayabilir. Böylece bulut teknolojisi gibi aygıt takılıp çıkarılabilen ortamlarda iyi çalışır.

Clients (Kullanıcılar)

ArcGIS Server sitesi kullanıcılarını şu şekilde isimlendirebiliriz.

  • Web Tarayıcılar: ArcGIS Server sitesi bünyesindeki servislere web tarayıcılar aracılığıyla ulaşmak mümkündür.
  • Mobile Aygıtlar: Akıllı telefonlar ve tabletler gibi taşınabilir aygıtlar ile web uygulamalarına ve web servislerine ulaşılabilir. Harita görüntüleme, yer bulma gibi uygulamalara rahatlıkla erişilebilmektedir.
  • ArcGIS Exploerer: ArcGIS Explorer görsel ve navigasyon için hazırlanmış ücretsiz bir masaüstü uygulamasıdır. ArcGIS Server servislerinizi veri olarak ekleyip zengin içerikli görüntü elde edebilirsiniz.
  • ArcGIS Desktop: ArcGIS Desktop uygulaması hem ArcGIS Server servislerini tüketebilir hem de yönetim aracı olarak kullanabilir. Bazı araçlar sayesinde sunucuya yayınlar sunmanız mümkündür. Bazı desktop uygulamalarını ArcMap, ArcCatalog, ArcGlobe, and ArcReader olarak sıralayabiliriz. Catalog ile uygun URL adresi ile CBS sunucularına bağlanabilirsiniz.
  • ArcGIS Engine: ArcGIS Engine uygulamaları CBS sunucularından faydalanır. ArcGIS Engine  geliştirircileri yazdıkları uygulamalar aracılığıyla CBS sunucularına veri gönderebilirler.

Kaynak: http://resources.arcgis.com/en/help/main/10.1/index.html#//0154000003p4000000

ArcGIS Server 10.1 Server Yenilikleri

4 Haz

Bir önceki blog paylaşımında ArcGIS Server 10.0 mimarisinden bahsetmiştim. Bu paylaşımın amacı ArcGIS Server 10.0 mimarisi ile 10.1 mimarisi arasındaki farkları görebilmekti. Bundan sonraki paylaşımlar 10.1 üzerinden ve çıkarsa daha yeni versiyonlar üzerinden devam edecektir. Bu yazımızda 10.1 versiyonunun getirdiği yenilikler üzerinden ilerleyeceğiz.

ArcGIS Server 10.1 verisyonu 64 bit bir uygulama olarak çalışır. Böylece CBS hizmetleri için donanım özelliklerinden tam olarak yararlanılır. Bu değişiklik, ArcGIS sunucularının ölçeklenebilirliğini arttırmak için yapılmıştır. 64 bit donanımlar artık mevcut endüstriyel standart haline geldiği göz önüne bulundurularak 32 bit işletim sistemlere verilen destek durdurulmuştur.

ArcGIS Server 10.1 Kurulum Yenilikleri

ArcGIS Server kurulumu önemli ölçüde basitleştirilmiştir. Önceki sürümlerde kurulum sırasında izlenen birçok adım kaldırılmıştır. Yeni özellikleri şu şekilde sıralayabiliriz.

  • Artık .Net Framework veya Java Runtime gibi yüklemelere gerek kalmıyor.
  • Ayrı bir sunucu (Microsoft IIS, WebSpahare, v.b) ile entegrasyona gerek kalmıyor. Artık sunucu için ArcGIS kurulumu yaptığınızda, web yönetim araçları ve uygulamalarıyla servis tabanlı bir CBS sunucusu(GIS Server) karşımıza çıkıyor.
  • CBS kaynaklarınıza ulaşmak için kurulum sırasında sizden tek bir kullanıcı hesabı istenir. Bu hesaba ArcGIS Server hesabı denir. 10.1 sürümünde kurulum sonrası adımlar ve ayrı ayrı ayarlanan SOM, SOC ve ArcGIS web servis hesapları yoktur.
  • DCOM bağımlılığı yoktur.

Birden fazla bilgisayar üzerine dağıtılmış kurulum yapmak basitleştirilmiştir. Her bilgisayarda aynı kurulumu yapılır, daha sonra ArcGIS Server Manager üzerinden bağlantılar gerçekleştirilir.

Windows ve Linux Ayrımı

Önceki versiyonlarda Microsoft .Net Framework ve Java platromu için sunulan ArcGIS Server, artık 10.1 versiyonuyla işletim sistemi seviyesine çekilmiştir. Kurulumlar Microsoft için ArcGIS(Server)  ve Linux için ArcGIS(Server) şeklinde yapılmaktadır.

ArcGIS Server 64 bit

ArcGIS 10.1 versiyonu 64 bit uygulama olarak çıkmıştır ve 32 bit işletim sistemi desteği durdurulmuştur.

SOM ve SOC modeli artık ArcGIS Server sitesi

Önceki ArcGIS Server versiyonlarında CBS sunucusu(GIS Server) SOM(Server Object Manager) ve SOC(Server Object Container) şeklinde iki bileşenden oluşmaktaydı. SOC bileşenleri GIS servislerinde barıdırılmaktadır ve SOM bileşeni tarafından yönetilir ve kullanıcıların hizmetine sunulur.

ArcGIS Server 10.1 ile birlikte SOM-SOC modeli ArcGIS Server sitesi şeklinde değiştirilmiştir. Bir site, bir veya birden fazla makine(GIS Server) üzerine yapılmış dağıtımdır. 10.1 ile gelen site mimarisi SOM-SOC modelinden daha sağlamdır. Hata riskini azaltır, yeni makinelerin eklenmesini ve mevcutların yönetimini kolaylaştırır.

ArcGIS Web Adaptör

ArcGIS Web Adaptor, ArcGIS Sunucusunun kendi web sunucunuz ile çalışması için yapılan bir kurulumdur. ArcGIS Server dış dünyaya REST ve SOAP servisleri sunabilmektedir. Eğer siteniz için kendi özel URL adreslerinizi ayarlamak istiyorsanız veya web sunucunuzun güvenlik modeli ile entegrasyon sağlamak istiyorsanız ArcGIS Web Adaptor kurulumunu yapmalısınız. Bu bileşen, eğer birden fazla makine ile bir siteyi yapılandıracaksanız ve güvenliği sıkılaştırmak istiyorsanız önerilir.

Kaynak: http://resources.arcgis.com/en/help/install-guides/arcgis-server/10.1/index.html#/What_s_new_in_the_ArcGIS_10_1_for_Server_install/01nm0000000m000000/

ArcGIS Server 10.0 Dağıtılmış Sistem Mimarisi

3 Haz

ArcGIS Server, sunduğu hizmetleri birden çok makine üzerine dağıtarak ölçeklenebilir bir sistem mimarisi sunmaktadır. ArcGIS sunucusunu ilk kez kuruyorsanız büyük olasılıkla tüm bileşenlerini aynı makine üzerine kurarak test edeceksiniz. ArcGIS Server uygulamanızı farklı makinelere dağıtmak istiyorsanız dağıtılmış kurulum(distributed installation) yapmalısınız. Bu sayede sisteminize erişen kullanıcı sayısı için kabul edilebilir bir düzeyde bir performans elde edebilirsiniz.

ArcGIS Server için yapılan dağıtılmış kurulum sayesinde sistem bileşenleri aynı yerel ağda birden fazla makine üzerinde barındırılır. Aşağıdaki grafikte ArcGIS Server bileşenlerinden SOM(Server object manager), SOC(server object container) ve Web sunucusunun farklı makineler üzerinde dağıtıldığını görebiliriz. Bu yapı Arcgis Server 10.0 için hazırlanmıştır. Daha sonraki versiyonlarda değişiklikler olabilir.

ArcGIS Server Mimarisi
ArcGIS Server 10.0 Mimarisi

Dağıtılmış şeklide kurulmuş olan ArcGIS Server sistemine daha fazla makine ekleyerek dışarı sunulan hizmeti daha da iyileştirmek mümkün hale gelmektedir. CBS (GIS) işlemlerinde yük çekici işlemler(container processes) CPU kaynağını çok fazla tükettiğinden sisteme birden fazla SOC makinesi dahil etmek bu yükün paylaşılmasını ve sistemin iyileştirilmesini sağlamaktadır.

ArcGIS Server bileşenlerini farklı makineler üzerinde akıllıca dağıtmak donanım kaynaklarınızın en etkin şekilde kullanılmasını sağlar. Örneğin kullanabileceğiniz makine sayısı yeterli değilse Web sunucusunu ve SOM bileşenini aynı makine üzerinde barındırabilirsiniz. Çünkü SOM, diğer bileşenlere nispeten daha az bellek kullanır.  Kalan donanım kaynakları da CBS sunucusunun işleyebileceği yükü dengelemek için SOC makinelerine aktarılabilirsiniz.

Dağıtılmış ArcGIS Server kurulumu yapmak, ArcGIS Desktop veya ArcGIS Engine kurulumuna benzemez. Çünkü birbiri ile konuşan makineleri doğru şekilde yapılandırmalısınız. SOM makinesinin sistemdeki bir SOC makinesine istekte bulunabilmesi gerekmektedir. Her makine aynı veri kümesi ve dizini ile çalıştığından her makine ortak bir isimlendirme kuralı (UNC path) ile aynı kayna erişmelidir.

Güvenlik mekanizmaları bazen makineler arasında iletişim sorunu çıkarabilir. Örneğin SOC hesabı farklı makineler üzerinde okuma ve yazma izinleri gerektirebilir. Bu sebeple ArcGIS Server bileşenleri arasında açık bir şeklide iletişim kurmaları gerektiğinden bu bileşenler arasında güvenlik duvarına gerek yoktur. Örneğin SOM ve SOC arasında veya SOM ve Web sunucusu arasında güvenlik duvarı gerekmez.
Ayarların Yapılması
Dağıtılmış bir ArcGIS Server sisteminin hizmete sunulması için atılacak ilk adım yapılandırma tasarımıdır. SOM, SOC, Web Application Developer Framewrok (ADF) ve Web Service endpoint bileşenleri aynı makineye yüklenebilir veya birden fazla makine üzerine dağıtılabilir. ADF Runtime Web sunucusu gibi aynı makinede yüklü olmalıdır.

ArcGIS Server Manager sunucunuzu yönetmenize yardımcı olan ve basit web uygulamaları oluşturmanızı sağlayan isteğe bağlı bir bileşendir. Bu bileşen iki parçadan oluşmaktadır. Bunlar Service Manager ve Application Manager olarak adlandırılır. Bu iki bileşen de aynı makine üzerinde veya farklı makineler üzerine dağıtılmış olabilir. Service Manager bileşeni Web servislerinin yüklü olduğu makinede servisleri oluşturmayı ve yönetmeyi sağlar. Application Manager bileşeni ise ADF yüklü makinedeki Web uygulamalarını oluşturmayı ve yönetmeyi sağlar.

GIS Servis kurulumu için buradan ve WEB Application kurulumu için de buradan bileşenlerin doğru yüklenmesine yardımcı olacak bilgiler verilmektedir.

Verileriniz CBS sunucusu (GIS Server) ile aynı yerel ağ üzerinde olmalıdır. Sunucunuzu Manager üzerinden yönetmiyorsanız ağınızda bir ArcGIS Desktop olmalıdır. Verilerinizin ve ArcGIS Desktop uygulamasının diğer CBS sunucu bileşenleri ile aynı makinede bulundurmamalısınız.

Kaynak: http://help.arcgis.com/en/arcgisserver/10.0/help/arcgis_server_dotnet_help/index.html#/Configuring_a_multiple_machine_deployment/0093000000m7000000/

JavascriptSerializer MaxLength Değerinin Aşılması

1 Haz

.Net Framework üzerinde veri transfer mekanizmalarını oluştururken attığımız adımlardan biri de serileştirme işlemidir. Serileştirme işlemlerini Binary, XML veya JSON formatlarında yapabilmekteyiz. Bu yazıda, JSON serileştirme işlemini gerçekleştirirken karşılaşılan bir sorun olan varsayılan olarak ayarlanmış maksimum JSON serileştirme değerinin aşıldığı durumlarda alınan hataları bir ölçüde bertaraf etmeyi inceleyeceğiz.

Örnek uygulamaya geçmeden önce .Net Framework ortamında JSON formatında serileştirme işlemi için gerekli olan ekipmanlardan bahsedelim. Bir nesnenin JSON formatında serileştirilmesi(serialization) veya JSON formatındaki bir verinin .Net nesnesine dönüştürülmesi(deserialization) işlemi için kullanılan referens “System.Web.Extensions”. Projemize bu referansı ekledikten sonra artık ihtiyaç duyduğumuz JavascriptSerializer sınıfına ulaşabiliriz.

Örnek uygulamamızda, verinin büyük olmasını amaçladığımız için bir dosyayı okuyarak JSON formatına dönüştüreceğiz.

Dosya okuma işlemi için aşağıdaki gibi basit bir metod oluşturuyoruz.

private static string readFile()
{
     const string targetDataFile = @"D:\data.txt";

     StreamReader reader = new StreamReader(targetDataFile);

     var result = reader.ReadToEnd();

     return result;
}

Bu metoddan elde ettiğimiz veriyi ise JSON dönüşümünü yapmak için bir başka metod içerisinde kullanıyoruz.

private static string getSerializedFile()
{
    var data = readFile();

    var serializer = new JavaScriptSerializer { MaxJsonLength = int.MaxValue };

    var serialized = serializer.Serialize(data);

    return serialized;
}

Serileştirme işlemi JavascriptSerializer sınıfının Serialize() metodu yardımıyla gerçekleştirilmektedir. JavascriptSerializer sınıfı, MaxJsonLength adında bir property barındırmaktadır. Aksi belirtilmediği taktirde bu property değeri 4MB veriye karşılık gelecek şekilde 2097152 olarak alınır. 4MB’tan fazla veriler için serileştirme sırasında hata verecektir. Bu property için buradan bilgi alabilirsiniz.

Hata InvalidOperationException başlıkı olup, içeriği şu şekildedir: Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.

Örnek uygulamamızda MaxJsonLength property değerini int.MaxValue olarak belirledik. Bu da yaklaşık 2GB civarı bir büyüklüktür.

Operatörlerin Aşırı Yüklenmesi (Operator Overloading C#)

27 May

Bu yazımızın konusu geliştiriciler tarafından oluşturulan sınıflar veya yapılar(struct) üzerinde operatörlerin aşırı yüklenmesidir. Operatörlerin aşırı yüklenmesi, bir operatörün bir nesne için bizim istediğimiz şekliyle çalışabilecek hale getirilmesidir diyebiliriz. Örneğin bir (+) operatörü varsayılan olarak iki sayının toplamı bulmak için veya iki ayrı metnin birleştirilmesi için kullanılır. Bazen yazdığımız sınıflara ait nesneler üzerinde operatörleri kullanmak isteriz. Bu durumda sınıfımızda bir takım değişiklikler yapmak zorundayız.

Bir örnek uygulama üzerinden operatörlerin aşırı yüklenmesini incelemeye çalışalım. Örneğimizin senaryosunda aşırı yükleme işlemini uygulamak için Price adında bir sınıf oluşturup bu sınıfa Cost adında bir property ekleyelim. İki farklı Price nesnesi üzerinden (+) gibi operatörleri aşırı yüklemeye çalışalım.

public class Price
{
      public double Cost { get; set; }

      public static double operator +(Price e1, Price e2)
      {
          return e1.Cost + e2.Cost;
      }
}

En basit gösterimi ile Price sınıfında (+) operatörünün aşırı yüklenmiş halini görüyoruz. Bir operatörün aşırı yüklenmesi bir takım kurallar içermektedir. Bunlar:

  • Operatör fonksiyonu static olmalıdır.
  • Operatör fonksiyonu, aşırı yüklenecek operatörün anahtar kelimesini belirtmelidir.
  • Operatör fonksiyonunun parametreleri, işlenecek tiplerdir.
  • Operatör fonksiyonunun geri dönüş türü belirlenmelidir.

Bu sınıf için (+) operatörünün kullanımı, şu şeklide opacaktır.

 Price p1 = new Price { Cost = 40.10 };
 Price p2 = new Price { Cost = 40.10 };

 var sum = p1 + p2; // sum = 80.20

Artık (+) operatörü, Price nesneleri için bir işleve sahip. Bu işlev, Price nesnesinin Cost parametrelerinin toplamını almasıdır.

Eğer aşırı yükleme işlemini yapmasaydık ve (+) operatörünü aynı şekliyle Price nesnesinde kullanmaya çalışsaydık şu şekilde bir hata alacaktık: “Operator ‘+’ cannot be applied to operands of type ‘OperatorOverrideApp.Price’ and ‘OperatorOverrideApp.Price

Price nesnesine int, double, float gibi built-in tipler ile toplamak istersek sadece işlenen argümanlarda şu şeklide bir değişiklik gerçekleştirmek yeterli olacaktır.

public static double operator +(Price e1, double e2)
{
     return e1.Cost + e2;
}

Bu şekilde, kendi sınıflarımızda operatörlerin aşırı yüklenmesi işlemini incelemeye çalıştık. Örnek uygulamaya ait kodlara buradan ulaşabilirsiniz.

Yeni Dizüstü Bilgisayarımı Satın Aldım

21 May

2008 yılından bu yana kahrımı çeken emektar laptopuma veda zamanı geldi çattı. Çünkü onu emekli edip yeni dizüstü bilgisayarımı satın aldım. Emektar makinam Datron marka olup TW7A modelinde ve zamanının 2.4Ghz  hızında en iyi işlemcilerine sahipti. Markasının Datron olması sebebiyle ben ona “Patron” diyordum.

Yeni makinam ise ASUS N56VZ. Son bir kaç haftadır bilgisayar araştırıyordum. Onu mu alsam bunu mu alsam derken en iyisi ben bu ASUS’u alayım diye karar kıldım. Asus için yakıştırmam ise “AL SUS” oldu. Gerçekten bu yakıştırmayı hakeden bir ürün. Şiddetle tavsiye ederim. Ürünü bir mağazanın “portakal rengi” indirim günlerinde inanılmaz bir fiyata yakaldım ve hemen satın aldım.

Emektar ve Yeni İşçi
Emektar ve Yeni İşçi

Özellik Karşılaştırması

Emektar DATRON Yeni ASUS
intel centrino 2.4 Ghz İntel i7 3630QM 2.4 Ghz
250 GB HDD 1 TB HDD
2GB RAM 16 GB RAM
512 MB Ekran kartı 4 GB Ekran Kartı
DVD Yazıcı Blue Ray Yazıcı

Mapping İşlemleri ve Automapper Performans Testleri

10 May

Programlama dünyasında nesneler arası aktarım yapılması amacıyla geliştirilmiş olan Automapper kütüphanesi üzerinde yaptığım performans sonuçlarını yazmak istedim.

C# kodu ile geliştirdiğim örnek uygulama üzerinde sırsıyla 10, 100, 1000, 10000 ve 100000 kayıt üzerinde üç farklı şekilde Mapping işlemi yapmayı denedim.

Örnek senaryoda Product adında bir sınıf düşünün. Bu sınıfın 10 farklı property üyesi olsun. Ben bu 10 üyeli Product tipini taşımak istemediğimden ProductSummary adında 2 üyesi olan bir sınıf oluşturuyorum.

public class Product
{
   public int id { get; set; }
   public string Name { get; set; }
   public string Color { get; set; }
   public string Model { get; set; }
   public string Size { get; set; }
   ...
   ..
   .
}

public class ProductSummary
{
   public int id { get; set; }
   public string Name { get; set; }
}

Doğal olarak Product nesnesini bir şekilde ProductSummary nesnesine aktarmalıyım. Bu işlemi Automapper kütüphanesi ile ve manuel olarak denediğimde ve süreleri milisaniye cinsinden ölçtüğümde ilginç rakamlarla karşılaştım.

List<Product> products = new List<Product>();

Kayıt sayısı sırayla 10, 100, 1000, 10000 ve 100000 olarak değiştiriliyor ve her seferinde Mapping işlemi deneniyor.

Mapping-1 (Yöntem-1 Foreach döngüsüyle tek tek Mapping işlemi)

foreach (var product in products)
{
    ProductSummary summary = Mapper.Map<Product, ProductSummary>(product);
}

10             kayıt için süre    121 milisecond
100          kayıt için süre    127 milisecond
1000       kayıt için süre    155 milisecond
10000     kayıt için süre    498 milisecond
100000  kayıt için süre    5298 milisecond

Mapping-2 (Yöntem-2 Kolleksiyonu direk mapping işlemine sokmak)

IEnumerable<ProductSummary> summary = Mapper.Map<IEnumerable<Product>,
                                    IEnumerable<ProductSummary>>(products);

10           kayıt için süre    133 milisecond
100         kayıt için süre    126 milisecond
1000      kayıt için süre    221 milisecond
10000    kayıt için süre    152 milisecond
100000  kayıt için süre    339 milisecond

Mapping-3 (Yöntem-3 Automapper kullanmadan manuel olarak nesneleri oluşturmak)

foreach (var product in products)
{
    ProductSummary summary = new ProductSummary();
    summary.id = product.Id;
    summary.Name = product.Name;
}

10           kayıt için süre    1 milisecond
100         kayıt için süre    1 milisecond
1000      kayıt için süre    2 milisecond
10000    kayıt için süre    4 milisecond
100000  kayıt için süre    42 milisecond

Mapping-4 (Yöntem-4 LINQ Extension metodlar yarımıyla mapping işleminin gerçekleştirilmesi)

var data = products.Select(summary=>
                 new ProductSummary{
                    Id= summary.Id,
                    Name = summary.Name
});

10           kayıt için süre    1 milisecond
100         kayıt için süre    1 milisecond
1000      kayıt için süre    1 milisecond
10000    kayıt için süre    1 milisecond
100000  kayıt için süre    1 milisecond

Mapping Raporları
Mapping Raporları

Bu sonuçlara göre Automapper kütüphanesi Mapping işlemlerinde biraz yavaş kaldığı aşikardır. En hızlı yöntemin LINQ Extension metodları yardımıyla Mapping işleminin olduğu ortaya çıkmaktadır. 100.000 kaydın mapping işlemine tabi tutulması 1 milisaniye sürmektedir. Aynı işlem Automapper kütüphanesi ile 5000 milisaniyeden fazla sürmektedir. Yani zaman probleminin olmadığı uygulamalarda Automapper kullanılabilir. Ancak işlemleri uzun sürede bitirmesi amacıyla yazılmış bir uygulama şu ana kadar hiç görmedim.

Bir sonraki yazıda görüşmek dileğiyle.

Asp.Net MVC JSON Model Bining

7 May

Asp.Net MVC mimarisinde yer alan model binding konusunu daha önceki yazılarda ele almıştık. Bu yazıda ise model binding işlemini JSON nesneleri ile uygylamaya çalışacağız. Web projelerinde ihtiyaç duyduğumuz  javascript tabanlı sorguları gerçekleştirmek için JSON nesnelerini .NET nesnelerine dönüştürmemiz gerekebilir. Request data olarak JSON nesnelerini POST edebilmeliyiz.

Örnek Uygulama

Örnek uygulama olarak bir ürün arama işlemini JSON formatındaki verileri bir Action metoda POST edeceğiz.

Öncelikli olarak Request ile gelen JSON fromatındaki veriyi deserialize ederek .Net nesnelerine dönüştürecek olan ModelBinder sınıfımızı oluşturmalıyız.

public class JsonModelBinder : IModelBinder
{
     public object BindModel(ControllerContext controllerContext,
                             ModelBindingContext bindingContext)
     {
          if (controllerContext == null)
             throw new ArgumentNullException("controllerContext");

          if (bindingContext == null)
             throw new ArgumentNullException("bindingContext");

          var serializer = new DataContractJsonSerializer(bindingContext.ModelType);
          var deSerialized = serializer.ReadObject(
                             controllerContext.HttpContext.Request.InputStream);

          return deSerialized;
    }

}

DataContractJsonSerializer sınıfının ReadObject metodu Request üzerinden ile gelen veriyi (InputStream), ModelBindingContext sınıfının ModelType parametresine göre uygun .Net tipine dönüştürür.

Şimdi de ModelBindingContext sınıfına gönderilecek olan tipi hazırlamalıyız.

[DataContract]
[ModelBinder(typeof(JsonModelBinder))]
public class JsonProductSearchRequest
{
     [DataMember]
     public string Name { get; set; }
     [DataMember]
     public string Color { get; set; }
}

System.Runtime.Serialization isim alanına dahil olan DataContract ve DataMember attribute tipleri sınıfları ve sınıf üyelerini serileştirilebilir hale getirmek için kullanılırlar. (Yeri gelmişken söylemekte fayda var; Bir tipi serileştirmek JSON, XML veya Binary şekillerde olabilmektedir. Biz örneğimizde JSON serileştirme üzerinde duracağız). JSonProductSearchRequest sınıfımızı, model binding sırasında ihtiyaç duyulan attribute olan ModelBinder ile imzalıyoruz, parametre olarak ise daha önceden hazırladığımız JsonModelBinder tipini gönderiyoruz.

Artık Controller tarafında ihtiyaç duyulan Action Metodları hazırlayabiliriz.

public class ProductController : Controller
{
   [HttpPost]
   public JsonResult JsonSearch(JsonProductSearchRequest request)
   {
       return null;
   }
}

JsonSearch Action metodu, daha önceden hazırladığımız JsonProductSearchRequest tipinde bir parametre almaktadır.

Şimdi hazırladığımız bu metoda fiddler yardımıyla bir istek (request) göndererek durumu incelemeye çalışalım.

Fiddler Json POST
Fiddler Json POST

Fiddler aracında Composer sekmesinden Request Tipini POST olarak seçiyoruz. Sunucudaki uygulama linkimizi girerek Request Body kısmına uygun JSON verisini giriyoruz. Execute butonuyla çalıştırdığımızda kodumuza geçip “break point” ile takip edersek:

Json Model Binder
Json Model Binder

Gönderdiğimiz verinin POST edildiğini rahatlıkla görebiliriz.

Bu şekilde etkili sonuç veren bir çözüme ModelBinding nimetlerinden faydalanarak ulaşmayı başardık. JSON tabanlı arama işlemlerini rahatlıkla bu şekilde gerçekleştirebiliriz. Ben bu örnekte View sayfalarıyla uğraşmamak adına fiddler aracından faydalanmayı uygun gördüm.

Bir sonraki yazıda görüşmek üzere.

Asp.Net MVC Custom Controller Factory

4 May

Asp.net MVC mimarisini benim için değerli kılan özelliklerinden başında genişletilmeye uygun olarak tasarlanmış olması gelmektedir.

Bu yazımızda Asp.Net MVC yaşam alanına giren bir isteği(request) ilk karşılayan Controller mekanizmasının özelleştirilmesi üzerinde duracağız. MVC mimarisinde Controller tipleri belli kurallar dahilinde tanımlanmıştır. Bu kuralların dışına çıkmak istediğimizde kendi isteğimize göre özel kurallar oluşturarak sisteme dahil etmemiz gerekmektedir. Default olarak tanımlanmış Controller kurallarından biri de Controller sınıflarının kurucu metodları (constructor) parametresiz olmasıdır.

Controller
Controller

Bu yazımızda parametresiz constructor metodunu ihlal ettiğimizde karşılaşacağımız sorunlar ve çözümleri üzerinde duracağız.

Parametresiz Constructor Hatası
Parametresiz Constructor Hatası

Parametresiz constructor kuralını ihlal ettiğimizde hemen bir hata ile karşılaşırız. Burada yapmak istediğimiz IoC (Inversion of Control) mantığında Controller sınıfına dışarıdan bir nesne(securityService) enjekte etmektir. Bu işlem için piyasadaki Ioc kütüphanelerini kullanabiliriz. Piyasada şu anda kullanılan kütüphaneler widsor, structuremap, ninject,… şeklinde sıralanabilir. Şu anda konumuz olmasa da IoC kütüphanelerinin yaptığı işten hemen kısaca bahsedelim. IoC kütüphaneleri interface gibi soyut tiplere karşılık olarak belirlediğimiz somut sınıflara ait nesneleri ihtiyaç duyduğumuzda oluşturarak bize sunarlar. Bu sayede “new” anahtar sözcüğü ile Controller içinde nesne oluşturarak somut tiplere bağımlı kalmamış oluruz.

Bu kısa notun ardından kendi tasarladığımız ControllerFactory sınıfımızı oluşturmaya başlayalım.

public class IocControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(

    RequestContext requestContext, Type controllerType)
    {
         return (IController)ObjectFactory.GetInstance(controllerType);
    }
}

DefaultControllerFactory sınıfının GetControllerInstance metodunu ezerek Controller nesnesi oluşturma işlemini StructureMap IoC container kütüphanesine yükledik. StructureMap kütüphanesi, önceden tanımladığımız interface ve sınıf eşleştirmesini yaparak constructor parametresi olarak kullanılan interface tipine karşılık bir somut nesne sunmaktadır.

public static class ContainerBootstrapper
{
     public static void BootstrapStructureMap()
     {
         ObjectFactory.Initialize(x =>
                  x.For<ISecurityService>().Use<SecurityService>());
     }
}

ContainerBootstrapper static sınıfında tanımladığımız BootstrapStructureMap metodu içerisinde interface tipine karşılık bir somut sınıf belirlenmektedir. ISecurityService interface tipi için SecurityService somut tipini kullan demiş olduk.

Hazırladığımız düzeneği çalıştırabilememiz için son olarak Global.asax içerisinde son hamlelerimizi yapmamız gerekiyor.

protected void Application_Start()
{
    .....
    ....

    ContainerBootstrapper.BootstrapStructureMap();

    ControllerBuilder.Current.SetControllerFactory(new IocControllerFactory());

}

Öncelikle ContainerBootstrapper.BootstrapStructureMap(); metodu ile eşleştirme işlemini gerçeklştiriyoruz. Ardından ControllerBuilder sınıfı yardımyla kendi özel conrtoller factory tipimiz olan IocControllerFactory tipini sisteme tanıtıyoruz. Artık DefaultControllerFactory sistemden çıktı ve yeni oluşturduğumuz factory tipi sistemimize dahil oldu.

Parametreli COntroller Constructor
Parametreli COntroller Constructor

Programı çalıştırdığımızda IsecurityService tipine karşılık olarak bir SecurityService nesnesi oluşturulmuştur.

StructureMap IoC container kütüphanesi hakkında detaylı bilgiyi buradan bulabilirsiniz.