Burak Selim Senyurt(MVP)
Matematik Mühendisi bir .NET Severin Yazıları...

NedirTv?com 4ncü Yıl Seminerleri

Çarşamba, 31 Mart 2010 17:00 by bsenyurt

2006 Mart ayında yayın hayatına başlayan nedirtv?com, 10 Nisan Cumartesi günü İstanbul' da düzenleyeceği etkinliklerle 4. yılını kutluyor. Konularında uzman nedirtv?com editörleri tarafından, beş farklı oturumda gerçekleştirilecek etkinliğimizde sizleri de aramızda görmeyi istiyoruz. Seminer programı ile ilgili detaylı bilgiler aşağıda yer almaktadır. Seminere katılmak için kayıt formunu doldurmanız gerekmektedir.

Not: Seminerlere katılım ücretsizdir. Kontenjan 100 kişi ile sınırlıdır.

09:45 Açılış
10:00 HTML 5 - Daron Yöndem
11:00 ASP.NET MVC 2 - Selçuk Yavuz

12:30 Ara

14:00 Microsoft Ajax Library(ASP.NET AJAX 4) - Uğur Umutluoğlu
15:00 WCF Eco System - Burak Selim Şenyurt
16:30 Windows Server AppFabric - Burak Selim Şenyurt
17:00 Hediye Çekilişi ve Kapanış

Tarih: 10 Nisan 2010 Cumartesi
Yer: Microsoft İstanbul Ofisi Bellevue Residence Levent Mahallesi, Aydın Sokak. No:7 Levent İstanbul
Kroki için tıklayın

Kayıt formuna bu linkten ulaşabilirsiniz.

Tags:   ,
Categories:   Seminerler
Actions:   E-mail | del.icio.us | Permalink | Yorumlar (1) | Comment RSSRSS comment feed
Bookmark and Share

Screencast - Ajax Enabled WCF Service’ lerin Silverlight ile Kullanılması

Çarşamba, 31 Mart 2010 14:35 by bsenyurt

Merhaba Arkadaşlar,

Daha önceki görsel derslerimizde WCF RIA Service ve Proxy bazlı WCF Service örneklerinin, Silverlight tarafında nasıl kullanılabildiklerini yeri geldikçe irdelemeye çalışmıştık. Silverlight uygulamalarının ASP.NET gibi Web ortamlarında sunulduğu göz önüne alındığında, kullanabileceği servis tiplerinden birisi de AJAX Enabled WCF Service' leridir ki özellikle Web Form' lar üzerinde bu tip servisler sıklıkla kullanılmaktadır. Söz gelimi otomatik metin tamamlama işlemlerinde...(Aslında AJAX tabanlı WCF Service' leri dışında ASMX tipindeki AJAX Service' leri de söz konusudur ama bu görsel dersimizde ele alınmamaktadır)

İşte bu görsel dersimizde öncelikli olarak bir AJAX Enabled WCF Service geliştirip, bunu örnek bir Silverlight uygulamasında nasıl kullanabileceğimizi görmeye çalışıyor olacağız. Geliştireceğimiz örnekte servis ve Silverlight uygulamasının aynı domain içerisinde yer aldıklarını farz ediyor olacağız ki ilerleyen görsel derslerimizde ayrı domain' lerdeki servisleri nasıl değerlendirebileceğimizi de incelemeye çalışacağız. E haydi o zaman, ne duruyorsunuz? NedirTv? sponsorluğunda hazırladığımız görsel dersimizi izleyin.

Not : Dersin ilerleyen kısımlarında, arka planda bizim ufaklığın ve onu memnun etmeye çalışan ev ahalisinin derinden gelen seslerini duyabilirsiniz. Ama dikkati dağıtacak derecede olmayacaktır.

Süre : 14:27

Dosya Boyutu : 24 Mb

Download Etmek veya İndirmek İçin

SilverlightApplication6.rar (100,34 kb) [Örnek Visual Studio 2010 RC Sürümü üzerinde geliştirimiş ve test edilmiştir]

WCF WebHttp Services - Client Bazlı Cache

Salı, 30 Mart 2010 16:30 by bsenyurt

Merhaba Arkadaşlar,

Bir önceki yazımızda(WCF WebHttp Services - Server Bazlı Cache) hatırlayacağınız üzere WCF WebHttp Service' lerinde sunucu taraflı ön belleklemeyi(Server-Based Caching) incelemeye çalışmış ve bu işin birde istemci taraflı olanından bahsetmiştik. Aslında sunucu ve istemci taraflı ön bellekleme işleyişleri birbirlerinden tamamen farklıdır. Sunucu taraflı ön bellekleme işleyişinde, tamponlanan veriyi üreten operasyonun duration süresi dolana kadar çalıştırılmaması söz konusudur. Yani istemciden gelen ilk talebin sonucunun ön belleğe alınmasını takiben gelen taleplerde, sunucu tarafındaki operasyon kodları icra edilmemektedir. Ne varki istemci taraflı ön belleklemenin işleyişine göre sunucu tarafındaki kodlar icra edilir ve ön bellekleme yapılacağı, HTTP Cache-Control bilgisinin istemciye gönderilen cevabın(Response) Header kısmına eklenmesi ile anlaşılır. Bir başka deyişle ilk talepten sonra gelecek taleplerde yine servis kodunun çalıştırılması gündemdedir. Dolayısıyla ispatı ve analizi pekte kolay olmayan bir konu ile karşı karşıyayız. Bu yüzden en azından nasıl hayata geçirilebileceğini görmeye çalışacağız. Elbette bir örnek geliştirerek. Gelin tembellik etmeyerek bir önceki uygulamamızdan devam etmek yerine yeni bir örnek üzerinden istemci taraflı ön belleklemenin nasıl yapılacağını araştıralım. Öncelikle aşağıdaki servis kodlarına sahip olan bir WCF REST Service Application projemiz olduğunu düşünelim.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Web;

namespace Lesson7
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class FunnyService
    {
        List<Wallpaper> wallpapers = new List<Wallpaper>
            {
                new Wallpaper{ Id=1000, Name="Ahhh!", Image=File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/Images/Ahhh.jpg"))},
                new Wallpaper{ Id=1001, Name="Blue Light", Image=File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/Images/BlueLight.jpg"))},
                new Wallpaper{ Id=1002, Name="My Dear Manager", Image=File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/Images/Manager.jpg"))},
                new Wallpaper{ Id=1003, Name="No Sacrifice No Victory", Image=File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/Images/Sacrifice.jpg"))}
            };
               
        [AspNetCacheProfile("WallpaperCache")] //web.config dosyasında WallpaperCache ismi ile output cache konfigurasyonu yapılmaktadır.
        [WebGet(UriTemplate = "Wallpapers/{Name}")]
        public List<Wallpaper> GetWallpapers(string Name)
        {
            var result = (from w in wallpapers
                         where w.Name.ToLower().Contains(Name.ToLower())
                         select w).ToList();
            return result;
        }
    }

    public class Wallpaper
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public byte[] Image{ get; set; }
    }
}

GetWallpapers isimli operasyonun çalıştırılması sonucunda istemci tarafına, Images klasörü altında yer alan jpg uzantılı resim dosyalarına ait byte[] içeriklerini taşıyan ve Wallpaper tipinden nesne örneklerinden oluşan generic List<T> koleksiyonu döndürülmektedir(Elbette varsayılan mesaj formatına göre XML olarak). AspNetCacheProfile niteliği yardımıyla söz konusu operasyon için Caching işleminin icra edileceği bildirilir. Bu ön belleklemenin hangi kriterlere göre yapılacağına ait tanımlamalar ise web.config dosyası içerisinde aşağıdaki gibi belirlenir.

<?xml version="1.0"?>
<configuration>
 
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <caching>
      <outputCache enableOutputCache="true"/>
      <outputCacheSettings>
        <outputCacheProfiles>
          <!-- İstemci taraflı ön bellekleme query string parametresi veya Header kısımlarını dikkate almaz. Bu nedenle varyByParam niteliğine none değerini atanmış ve varyByHeader niteliği kullanılmamıştır. Dikkat edileceği üzere ön belleklemenin istemci taraflı olacağı location niteliği ile belirlenmiştir.-->
          <add name="WallpaperCache" duration="120" varyByParam="none" location="Client"/>
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>
  </system.web>

Konfigurasyon dosyasının devamı...

OutputCacheProfiles içerisine eklenen WallpaperCache profiline göre Cache süresi 120 saniyedir. Diğer taraftan istemci taraflı ön bellekleme işlemlerinde Querystring kullanımı bir faktör olmadığından varyByParam niteliğine none değeri atanmalıdır. Bu profilde belkide en önemli nokta location niteliğinin değerinin Client olarak belirlenmesidir. Böylece ön bellekleme işleyişinin istemci taraflı yapılacağı tayin edilimiş olur.

Tabi bu durumu incelemek için istemci tarafının da geliştirilmesi gerekmektedir. Nitekim istemci tarafına gönderilen cevabın Header kısmında, Caching ile ilgili bilgilerin bulunması gerekmektedir. Bu amaçla çok basit olarak aşağıdaki kodlara sahip bir Console uygulaması yazdığımızı düşünebiliriz (HttpClient ve diğer yardımcı tiplerin kullanımı söz konusu olduğundan REST Starter Kit' in parçası olan Microsoft.Http ve Microsoft.Http.Extension assmebly' larının referans edilmesi gerektiğini unutmayalım)

using System;
using Microsoft.Http;

namespace ClientApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // HttpClient nesnesi url adresine göre oluşturulur.
            HttpClient client = new HttpClient("http://localhost:1000/");

            Send(client);

            Console.WriteLine("Kapatmak için bir tuşa basınız");
            Console.ReadLine();

        }
        static void Send(HttpClient client)
        {
            Console.WriteLine("\nAradığınız kelimeyi girin\n");
            string word = Console.ReadLine();
            // Wallpapers için gerekli request string oluşturulur. word bilgisi kullanıcı tarafından girilmektedir.
            string requestString = String.Format("Wallpapers/{0}", word);

            // Get metodundan yararlanılarak sunucu tarafına ilgili talep gönderilir
            using(HttpResponseMessage responseMessage = client.Get(requestString))
               {
   
             // Sunucudan gelen cevap içerisinde yer alan Cache bilgisi ve ayrıca HTTP Statü koduna bakılır
                Console.WriteLine("{0}\n{1}\n",responseMessage.Headers.CacheControl.MaxAge,responseMessage.StatusCode);
           
                // İçerik okunur
               Console.WriteLine(responseMessage.Content.ReadAsString());
            }
        }
    }
}

İstemci uygulamadan kullanıcının girdiği kelimeye göre HTTP Get formatında bir talebinin gönderilmesi sağlanmaktadır. Sunucu tarafından çağırılan operasyona ait ön bellekleme işleminin istemci bazlı olduğu, istemci tarafına gönderilen cevap(Response) içerisinden öğrenilebilir. Bu amaçla örnek olarak HttpResponseMessage nesnesinin Header.CacheControl özelliği üzerinden yakalanan MaxAge değerine bakılmıştır. Bu değer dikkat edileceği üzere sunucu üzerinde belirtilen duration süresinin Timespan karşılığıdır(örneğimize göre 2 dakika).

Tabiki Caching özelliğini sunucu tarafında kapatırsak ki bunun için web.config dosyasında ilgili cache profile' in enabled niteliğine false değeri atamamız yeterlidir,

<add name="WallpaperCache" duration="120" varyByParam="none" location="Client" enabled="false"/>

ve aynı örneği yeniden test edersek aşağıdaki sonuçlar ile karşılaşırız.

çok doğal olarak bir ön bellekleme süresi olmayacaktır. Örneği Fiddler gibi bir araç yardımıyla incelediğimizde ise istemci tarafına dönen cevaba ait Cache bilgisini daha detaylı bir şekilde görebiliriz.

WCF WebHttp Service' ler ile ilişkili serimizde yer alan bir yazımızın daha sonuna geldik. Bu yazımızda istemci bazlı ön bellekleme işlemleri için ne gibi hazırlıklar yapılması gerektiğini gördük. En önemli noktanın web.config dosyası içerisinde belirtilen location niteliği olduğunu özetleyebiliriz. Tekrardan görüşünceye dek hepinize mutlu günler dilerim.

Lesson7_RC.rar (192,46 kb) [Örnek Visual Studio 2010 Ultimate Beta 2 Sürümünde geliştirilmiş ancak RC sürümü üzerinde de test edilmiştir]

WCF WebHttp Services - Server Bazlı Cache

Salı, 30 Mart 2010 00:05 by bsenyurt

Merhaba Arkadaşlar,

Şirketimi çok seviyorum. Nazar değmesin ama araştırma yapmam, yeni bir şeyler öğrenmem ve bunları ekip arkadaşlarımla paylaşmam için beni özellikle teşvik eden bir şirkette bulunmaktayım. Çalıştığım şirketin en güzel özelliklerinden biriside, Cuma günleri yapılan minik ikramları. Wink Her cuma değişik bir yiyecek ile karşılaşıyoruz. Geçtiğimiz Cuma' lardan birisinde ise yanda çektiğim resimde görülen gülen kurabiyelerimiz vardı. E böylesine güler yüzlü kurabiyeler ile gerekli glikozu aldıktan sonra içimden hemen eve gitmek gelmedi. Bunun yerine mesai sonrasında çalışma masamda oturup, etrafın sakinleşmesi ve sessizliğin artması ile birlikte bloğuma bir şeyler yazmaya karar verdim. Bir süredir WCF Eco System' in parçaları üzerinde yazmakta olduğum bir seri bulunmaktaydı. Bunu devam ettirmek ile Cuma gecesini güzelce tamamlayabileceğimi düşündüm. İşte bu günkü konumuz...WCF WebHttp Service' lerinde ön bellekleme(Output Caching).

WCF WebHttp Service' leri bildiğiniz üzere Web ortamı üzerinden sunulan hizmetlerdir. Bu sebepten Web tarafının sunucu ve istemci bazlı bazı yeteneklerini kullanabilirler. Örneğin Asp.Net Compatibility Mode ile çalıştırıldıklarında Asp.Net dünyasının Output Cache yeteneğine sahip olurlar. Bildiğiniz üzere Output Cache mekanizması sayesinde Web içeriklerine gelen taleplerin ön bellekten karşılanması ve bu sayede arka planda ilgili HTML çıktılarının üretilmesi için gerekli işlemlerin otomatikman atlanılması sağlanabilmektedir. Bu, özellikle üretim maliyeti yüksek olan ama belirli bir süre zarfı içerisinde değişmeyen sayfa içeriklerinin üretiminde oldukça performans arttırıcı bir tekniktir. Madem Web tarafında böyle bir yeteneğimiz bulunmaktadır, o halde neden bu kabiliyeti WCF Servislerinde de kullanamayalım? İşte bu yazımızda Asp.Net tarafında hazır olan bu alt yapının WebHttp Service' lerinde nasıl kullanıldığını incelemeye çalışıyor olacağız. İlk olarak konuyu sunucu bazlı ön bellekleme(Server Side Caching) olarak değerlendireceğiz. Serinin sonraki bölümünde ise istemci taraflı ön belleklemeyi ele alacağız. Dilerseniz vakit kaybetmeden kodlamaya başlayalım. Öncelikli olarak aşağıdaki WebHttp Service içeriğine sahip bir WCF REST Service Application geliştirdiğimizi düşünelim.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Web;

namespace Lesson6
{  
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class EinsteinService
    {
        // GetCategories isimli metodun çıktısının ön bellekleneceği AspNetCacheProfile niteliği ile belirtilir. Nitelikte parametre olarak kullanılan string bilgi ile web.config dosyasında bu metod için nasıl bir ön bellekleme yapılacağı set edilir. Ne kadar süre ile tutulacağı, parametre bazlı olup olmayacağı gibi...
        [AspNetCacheProfile("CategoriesCache")]
        [WebGet(UriTemplate = "Categories")]
        public List<string> GetCategories()
        {           
            string[] categories=File.ReadAllLines(HttpContext.Current.Server.MapPath("~/Kategoriler.txt"));
            return new List<string>(categories);
        }

        [AspNetCacheProfile("CategoriesByFirstLetterCache")]
        [WebGet(UriTemplate = "Categories/{firstLetter}")]
        public List<string> GetCategoriesByFirstLetter(string firstLetter)
        {
            string[] categories = File.ReadAllLines(HttpContext.Current.Server.MapPath("~/Kategoriler.txt"));
            return (from category in categories
                         where category.StartsWith(firstLetter,true,null)
                         select category).ToList();
        }
    }
}

Örneğimizde yer alan servisimizde iki operasyon yer almaktadır. Her iki operasyonda aşağıda örnek çıktısı olan Kategoriler.txt isimli text tabanlı dosyayı kullanmaktadır.

GetCategories operasyonu text dosyası içerisindeki tüm satırları string tipinden generic List koleksiyonu olarak geriye döndürmektedir. GetCategoriesByFirstLetter operasyonu ise aynı çıktıyı baş harflere göre üretmektedir. Bizim odaklanmamız gereken nokta ise her iki operasyon başında uygulanan AspNetCacheProfile niteliğidir(Attribute). Bu niteliklerin uygulanması ile söz konusu operasyonların çıktılarının ön bellekleneceği, çalışma zamanı ortamına bildirilmektedir. Her iki nitelikte birbirlerinden benzersiz olan takma adlar(Alias) ile işaret edilmektedir. Peki bu isimleri nerede değerlendireceğiz? Bu sorunun cevabı Web.config dosyasında yer alan Asp.Net Output Cache ayarlarında gizlidir...Wink Buradaki ayarlar ile hangi operasyon için nasıl bir ön bellekleme işleminin uygulanacağını belirtebiliriz. Örneğin operasyonların sonuçlarının ne kadar süreyle ön bellekte tutulacaklarını farklılaştırabiliriz. Yada parametre bazlı olanları...Örneğin GetCategoriesByFirstLetter operasyonunun çalışma zamanı HTML çıktılarının firstLetter bilgisine göre ön belleklenebileceğini belirtebiliriz. Tüm bu ayarlamalar için web.config dosyasına aşağıdaki eklemeleri yapmamız yeterlidir.

<?xml version="1.0"?>
<configuration>
 
  <system.web>
    <compilation debug="true" targetFramework="4.0" />

    <caching>
      <outputCache enableOutputCache="true"/>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="CategoriesCache" duration="120" location="Server" varyByParam="none" varyByHeader="Accept"/>
          <add name="CategoriesByFirstLetterCache" duration="300" location="Server" varyByParam="firstLetter" varyByHeader="Accept"/>
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>
  </system.web>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>

  <system.serviceModel>
    <!--Asp.Net Output Caching alt yapısını ve yeteneklerini kullanmak istediğimiz için, AspNet Compatibility modun açık olması önemlidir.-->
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <standardEndpoints>
      <webHttpEndpoint>
        <!--
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

</configuration>

Buradaki ayarlamalara göre CategoriesCache adı ile belirlenen operasyonlar 120 saniye süreyle ön bellekten getirilecektir. Ön bellekleme ortamının sunucu taraflı olduğu location niteliği ile belirtilmektedir. Bu ön bellek ayarında parametre kullanılmadığı(varyByParam="none") ve talebin(request) Header kısmına göre Accept tipinde olanların göz önüne alındığı ifade edilmektedir. Diğer yandan CategoriesByFirstLetterCache bildirimine bakıldığında sürenin 300 saniye olduğu ama bir öncekinden farklı olarak firstLetter parametresine göre ön bellekte ayrı ayrı görüntüler tutulacağı belirtilmektedir. Buna göre Categories/A gibi bir talep ile Categories/s gibi bir taleb için üretilen HTML çıktıları ön bellekte ayrı ayrı tutulacaktır. Tabi birden fazla parametrenin değerlendirilmesi gerektiği durumlarda ; işareti kullanılarak bildirilmeleri gerekmektedir. Örneğin varyByParam="firstLetter;productCount" vb.

Tabi yapımış olduğumuz bu anlatımın sonuçlarını test ederek görmemiz gerekiyor. Burada debug modu kullanarak talepler sırasında operasyon metodlarının içerisine ne zaman girilip ne zaman girilmediğini tespit ederek gerekli kontrolleri yapabiliriz. İşte size örnek test senaryoları;

1 - Önce URL üzerinden Categories talebini gönderin. Bu durumda tüm kategorilerin aşağıdaki şekilde olduğu gibi geldiğini göreceksiniz.

Şimdi 120 saniyelik süre dolmadan Kategoriler.txt üzerinde bir değişiklik yapın. Örneğin Mücehver isimli yeni bir kategori ekleyin veya bir kaç kategorinin ismini değiştirin yada silin. 120 saniyelik zaman dilimi içerisinde yeniden Categories talebinden bulunursanız yapmış olduğunuz değişiklilerin tarayıcıya getirilmediğini görebilirsiniz. Ancak 120 saniyelik ön bellek süresi dolduktan sonra değişiklikleri görebileceksiniz ve hatta Debug moddaysanız ilgili operasyon kodu içerisine tekrardan girildiğini fark edeceksiniz. Bu zaten ön belleklemenin çalıştığının ispatıdır.

2 - İkinci olarak parametre bazlı ön bellekleme yapıldığını test edebilirsiniz. Bu amaçla tarayıcı üzerinden örneğin Categories/A ve Categories/M taleplerinde bulunun. Debug modda ilerlerseniz testinizi daha başarılı bir şekilde yapabilirsiniz. Özellikle 300 saniyelik ön bellekleme süreleri dolmadan farklı harfler ile denemeler yaptığınızda, ön belleklenenler için operasyon koduna girilmediğini ama daha önceden talep edilmeyenler veya 300 saniyelik ön bellekte kalma süresini dolduranlar için kodun tekrar çalıştırıldığını gözlemleyebilirsiniz.

Bu sayede geliştireceğimiz WebHttp Service' lerin operasyonlarının hızlı sonuçlar üreterek daha performanslı ve verimli olmasını sağlayabiliriz. Bu yazımızdaki örneğimizde sunucu tarafında ön bellekleme işlemlerini gerçekleştirdik. Ancak birde istemci taraflı ön bellekleme(Client Based Caching) işlemlerinin söz konusu olduğunu belirtelim. Bunu serinin sonraki yazısında incelemeye çalışacağız. Tekrardan görüşünceye dek hepinize mutlu günler dilerim.

Lesson6_RC.rar (20,41 kb) [Örnek Visual Studio 2010 Ultimate Beta 2 Sürümünde geliştirilmiş ancak RC sürümü üzerinde de test edilmiştir]

Screencast - Silverlight Enabled WCF Services

Çarşamba, 24 Mart 2010 11:10 by bsenyurt

Merhaba Arkadaşlar,

Silverlight tarafında servis denildiğinde akla ilk gelen model WCF RIA Services' leridir. Esas itibariyle WCF Eco System' in bir parçası olan WCF RIA Service' ler Silverlight tarafında ele alınabilecek tek servis modeli değildir. Söz gelimi, aynı domain içerisinde yer alan bir WCF Service' i de, Silverlight istemcileri tarafından Proxy kullanımı ile tüketilebilir(Consume). İşte NedirTv? sponsorluğunda hazırladığımız bu görsel dersimizde serileştirilebilir bir tipi geriye döndüren bir operasyonu içeren Silverlight destekli bir WCF Service' inin, Proxy tabanlı olarak nasıl kullanılabileceğini incelemeye çalışıyoruz. Üstelik Proxy üretiminin bir faydası olarak ilgili servis operasyonu çağrısının asenkron olarak nasıl yapılabileceğini de göreceğiz.

Süre : 14:55

Boyut : 21.7 Mb

Download etmek veya izlemek için

SilverlightApplication4.rar (104,07 kb) [Örnek Visual Studio 2010 RC sürümü üzerinde geliştirilmiş ve test edilmiştir]

Entity Framework - Many To Many Relations - Link Tablosunda Israrcı Olmak

Çarşamba, 24 Mart 2010 09:35 by bsenyurt

Merhaba Arkadaşlar,

Bazen bebek adımları ile ilerlememiz gerekir. Özellikle yazılım alanında bazı konuları öğrenirken işin teorisinden önce pratik bir örneği adım adım geliştirmek son derece faydalıdır. Ado.Net Entity Framework ile ilişkili inclemelerimize devam edeceğimiz bu yazımızda bebek adımları ile ilerleyeceğiz.

Hatırlayacağınız üzere son iki yazımızda Many-To-Many ilişkileri nasıl ele alabileceğimizi incelemiştik. Many-To-Many ilişkilerin Entity Model'e olan yansımasında belkide en önemli nokta, ara bağlantı tablosunun taşınmıyor olmasıydı. Bu genellikle ara bağlantı tablosu üzerinde diğer tablolara ait Primary Key alanlarının bulunduğu durumlar düşünülerek meydana gelen bir sonuçtur. Nitekim ara tablonun Entity tarafına taşınmayışının herhangibir olumsuz maliyeti bulunmamaktadır. Ancak bazı durumlarda söz konusu ara bağlantı tablosunun ilerleyen zamanlarda ek alanlar ile genişlemesi söz konusu olabilir. Bu durumda ara bağlantı tablosunun Entity olaraktan Model Diagram içerisinde yer almasının avantajı olacaktır. Nitekim ileride eklenecen kolonlar için Entity Model tarafında sadece Conceptual Schema' yı güncellemek yeterlidir.

Dolayısıyla bu yazımızdaki amacımız, varsayılan olarak Entity Model Diagram üretilirken ortadan kaldırılan ara bağlantı tablosunun manuel olarak oluşturulmasını sağlama olacaktır. Başlangıçta Visual Studio 2010 Ultimate RC sürümü üzerinde oluşturduğumuz Console uygulaması içerisinde yer alan Entity Model diagramının aşağıdaki gibi olduğunu varsayıyoruz.

Tahmin edeceğiniz üzere Chinook veritabanı içerisinde yer alan Playlist-Track ilişkilerini değerlendirmekteyiz. Şekil üzerinde yer alan çarpı işareti mutlaka dikkatinizi çekmiştir. Aslında bu yapacağımız ilk hamle olacak. Aradaki Association nesnesini silmek. Bu durumda çok doğal olarak Playlist ve Track tablolarında yer alan ve birbirlerine olan geçişleri sağlayan Navigation Property' lerin de ortadan kaldırıldığını göreceğiz.

Ancak burada dikkat etmemiz gereken bir nokta bulunmaktadır. Silme işlemi sırasında Designer' ın aşağıdaki sorusu ile karşılaşacağız. PlaylistTrack tablosu her ne kadar Entity olarak ifade edilmese de, oluşturacağımız Entity' nin ileride veritabanında karşılık geldiği tablo ile ilişkilendirilmesi sırasında ele alınacaktır. Bu nedenle No seçimi yaparaktan silme işlemini icra etmemiz daha doğrudur.

Sıradaki adımımız ise veritabanında yer alan ve Playlist ile Track tabloları arasındaki Many-To-Many ilişkiyi gerçekleştiren tabloya karşılık gelen bir Entity tipinin oluşturulmasıdır. Yani veritabanında yer alan PlaylistTrack isimli tablonun karşılığı olan Entity tipinin üretilmesi. Bunun için Model diagramı üzerinden Add->Entity seçimini yapmamız yeterli olacaktır. Sonrasında ise Entity özelliklerini aşağıdaki gibi ayarlamamız gerekecektir.

 

Burada dikkat edilmesi gereken noktalardan birisi, Key Property özelliğinin kullanılmayışıdır. Nitekim bu alana senaryomuza göre gerek yoktur. Ara tablonun karşılığı olan PlaylistTrack Entity tipinin görevi, Playlist ve Track Entity tipleri arasındaki Many-To-Many ilişkiyi sağlamak olduğundan, bu Entity' lere ait Key özelliklerini barındırması yeterlidir. Buna göre yeni oluşturulan Entity içerisinde aşağıdaki şekilde görülen Scalar Property' lerin eklenmesi gerekir.

Yine dikkat edilmesi gereken önemli bir nokta vardır. PlaylistTrack Entity tipi içerisinde yer alan PlaylistId ve TrackId isimli alanlarının Entity Key özelliklerine true değer atanmıştır. Buna göre bu alanların Playlist ve Track tablosundaki karşılıkları ile ilişki kurabilmesi mümkün olacaktır. Dolayısıyla sıradaki adımımız tablolar arasındaki ilişkileri kurmaktır.

Not : Aslında PlaylistId ve TrackId alanlarının oluşturulması şart değildir. PlaylistTrack tablosuna ait bilgileri silmediğimizden Association' ları oluşturduğumuz sırada söz konusu alanların otomatik olarak üretileceğini görebiliriz. Bu tekniğide tercih edebilirsiniz. Şu andaki ilerleyişimize göre Association' ların oluşturulması sırasında Add foreign key properties to the... seçeneğini kaldırmamız gerekmektedir. Ancak kolonların oluşturulmasını otomatikleştirmek istiyorsak, bu seçeneği işaretli bırakmamız gerekmektedir. Böyle yaptığımız takdirde kolon adlarının pekte istediğimiz gibi olmayacağını, yeniden isimlendirmemiz gerektiğinide belirtmek isterim. Tercih size kalmış. Wink

Şimdi bir düşünelim. Bir Playlist'e bağlı birden fazla Track olabilir. Benzer şekilde bir Track birden fazla Playlist içerisinde yer alabilir. Buna göre Playlist ve Track varlıkları arasında Many-To-Many ilişki söz konusudur. Bunu zaten biliyoruz Smile Ancak bunun Entity Model diagram tarafında, şu andaki yapıya göre ifadesi nasıl olacaktır? Cevap; Playlist Entity' sinden PlaylistTrack Entity' sine ve benzer şekilde Track Entity' sinden yine PlaylistTrack Entity' sine doğru One-To-Many ilişki sağlayarak. Bunun için diagrama bir Association nesnesi eklenmesi yeterlidir(Add->Association).

Playlist -> PlaylistTrack

Dikkat edileceği üzere End özelliklerinden sol tarafta yer alanda Playlist bulunmaktadır. Playlist Entity tipi için Multiplicity özelliği 1(One) iken, sağ tarafta yer alan PlaylistTrack için *(Many) dir. Buna göre Playlist Entity tipinden PlaylistTrack Entity tipine doğru One-To-Many ilişki kurulmuştur. Üretilen Navigation Property' lerden PlaylistTrack olarak adlandırılanlar, çoğulluk nedeni ile PlaylistTracks olarak yeniden isimlendirilmiştir. Bu işlemin sonrasında diagramın yeni hali aşağıdaki gibi olacaktır.

Track -> PlaylistTrack

Bu kez Track Entity tipi üzerinden az önceki gibi PlaylistTrack Entity tipine doğru One-To-Many ilişki kurulmuştur. Sonuç olarak diagramın yeni hali aşağıdaki gibi olacaktır.

Sıradaki adımda oluşturulan yeni PlaylistTrack Entitiy tipinin, veritabanında yer alan Tablo karşılığı ile eşleştirilmesi gerekir. Bu sebepten PlaylistTrack Entity tipinin Mapping Details özelliklerinden aşağıdaki gibi gerekli eşleştirmenin yapılması şarttır. Hatırlayacağınız üzere ilk adımda Association nesnesini silerken tablonun kaldırılmamasını belirtmiştik. Bu sayede Table eşleştirmesini kolayca gerçekleştirdik.

Ancak işlemlerimiz bir türlü bitmek bilmemektedir. Sabredin, çok az kaldı. Takip eden adımda Referentail Constraint' lerin tanımlanması gerekmektedir. Normal şartlarda eğer Association' lar oluşturulurken Add foreign key properties to the...  işaretli olsaydı bunlarda ilgili alanlar ile birlikte otomatik oluşturulacaklardı. Bu nedenle izleyen şekillerde görüldüğü üzere ilgili eklemelerin yapılması gerekmektedir.

ve

Buraya kadar yaptıklarımızı özetleyecek olursak aşağıdaki adımları gerçekleştirdiğimizi ifade edebiliriz.

1- Entity' ler arasındaki Many-To-Many tipinden Relation silinir.

2- Veritabanında yer alan ama Entity Model tarafına aktarılmayan ara tablonun karşılığı olan tipin üretilmesi sağlanır.

3- Eklenen Entity tablosuna Entity Key özellikleri true olan ve diğer Entity' ler üzerinde karşılık düşen alanlar ile aynı tipten olan(Örneğimizde hepsi Int32) Scalar Property' ler ilave edilir.

4- Entity tipleri arasındaki One-To-Many ilişkiler(Association) tesis edilir.

5- Eklenen Entity nesnesi, veritabanındaki tablo ile ilişkilendirilir(Mapping).

6- Association' lar ile ilişkili olaraktan gerekli Referencial Constraints' ler tanınmlanır.

Artık konuyu basit bir örnek sonlandırabiliriz. Bu amaçla aşağıdaki program kodunu yazdığımızı düşünelim.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RelationEntityCreation
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ChinookEntities entities = new ChinookEntities())
            {
                var result = (from p in entities.Playlists.Include("PlaylistTracks.Track")
                              where p.PlaylistId == 3
                              select p).First();


                foreach (var r in result.PlaylistTracks)
                {
                    Console.WriteLine(r.Track.Name);
                }
            }
        }
    }
}

Örnek kod parçasında PlaylistId değeri 3 olan satıra bağlı olan Track' lerin çekilmesi sağlanmaktadır. Include metodu içerisinde belirtilen tanımlama önemlidir. Burada PlaylistTracks üzerinden Track Entity' sine ulaşılmaktadır. Bu sayede Playlist' e bağlı Track' lerinde yüklenmesi sağlanmış olur. Uygulama kodunun çalışmasının sonucu aşağıdaki gibidir.

Tabi bu kodun çalışması sonrasında SQL tarafında oldukça yoğun bir sorgunun üretilmesi söz konusudur.

SELECT
[Project1].[PlaylistId] AS [PlaylistId],
[Project1].[Name] AS [Name],
[Project1].[C1] AS [C1],
[Project1].[PlaylistId1] AS [PlaylistId1],
[Project1].[TrackId] AS [TrackId],
[Project1].[TrackId1] AS [TrackId1],
[Project1].[Name1] AS [Name1],
[Project1].[AlbumId] AS [AlbumId],
[Project1].[MediaTypeId] AS [MediaTypeId],
[Project1].[GenreId] AS [GenreId],
[Project1].[Composer] AS [Composer],
[Project1].[Milliseconds] AS [Milliseconds],
[Project1].[Bytes] AS [Bytes],
[Project1].[UnitPrice] AS [UnitPrice]
FROM ( SELECT
 [Limit1].[PlaylistId] AS [PlaylistId],
 [Limit1].[Name] AS [Name],
 [Join1].[PlaylistId] AS [PlaylistId1],
 [Join1].[TrackId1] AS [TrackId],
 [Join1].[TrackId2] AS [TrackId1],
 [Join1].[Name] AS [Name1],
 [Join1].[AlbumId] AS [AlbumId],
 [Join1].[MediaTypeId] AS [MediaTypeId],
 [Join1].[GenreId] AS [GenreId],
 [Join1].[Composer] AS [Composer],
 [Join1].[Milliseconds] AS [Milliseconds],
 [Join1].[Bytes] AS [Bytes],
 [Join1].[UnitPrice] AS [UnitPrice],
 CASE WHEN ([Join1].[PlaylistId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
 FROM   (SELECT TOP (1) [Extent1].[PlaylistId] AS [PlaylistId], [Extent1].[Name] AS [Name]
  FROM [dbo].[Playlist] AS [Extent1]
  WHERE 3 = [Extent1].[PlaylistId] ) AS [Limit1]
 LEFT OUTER JOIN  (SELECT [Extent2].[PlaylistId] AS [PlaylistId], [Extent2].[TrackId] AS [TrackId1], [Extent3].[TrackId] AS [TrackId2], [Extent3].[Name] AS [Name], [Extent3].[AlbumId] AS [AlbumId], [Extent3].[MediaTypeId] AS [MediaTypeId], [Extent3].[GenreId] AS [GenreId], [Extent3].[Composer] AS [Composer], [Extent3].[Milliseconds] AS [Milliseconds], [Extent3].[Bytes] AS [Bytes], [Extent3].[UnitPrice] AS [UnitPrice]
  FROM  [dbo].[PlaylistTrack] AS [Extent2]
  INNER JOIN [dbo].[Track] AS [Extent3] ON [Extent2].[TrackId] = [Extent3].[TrackId] ) AS [Join1] ON [Limit1].[PlaylistId] = [Join1].[PlaylistId]
)  AS [Project1]
ORDER BY [Project1].[PlaylistId] ASC, [Project1].[C1] ASC

Buuuwvvvvv!!!  Sealed Açıkçası ben bu tip bir tablonun eğer maliyet kaybı yoksa ısrarla eklenmesinden yana değilim. Yani Ado.Net Entity Framework gibi düşünüyorum. Fakat yazımızın başında da belirttiğimiz üzere ara tablonun, One-To-Many ilişkiler için gerekli olanlar dışında ek alanlar da içerebileceği durumlar söz konusu olabilir. Bu alanların zaman içerisinde tabloya eklenmesi ve Entity tarafına da taşınması gerektiği hallerde, Entity Model üzerinde söz konusu ara tablonun karşılığının olması, sadece Conceptual Model üzerinde müdahaleler yaparak işi kurtarmamızı sağlayabilir. Teorik olarak. Yine de anlattıklarımızın RC sürümü üzerinde yazıldığını belirtmek isterim. Yani ilerleyen sürümde farklılıklar söz konusu olabilir. Wink Böylece geldik bir yazımızın daha sonuna. Tekrardan görüşünceye dek hepinize mutlu günler dilerim.

RelationEntityCreation_RC.rar (52,15 kb) [Örnek Visual Studio 2010 Ultimate RC sürümü üzerinde geliştirilmiş ve test edilmiştir]

Screencast - WCF RIA Services, OData, Excel PowerPivot

Salı, 23 Mart 2010 09:05 by bsenyurt

Merhaba Arkadaşlar,

Yeni bir maceraya daha hazır mısınız? Evet dediğinizi duyar gibiyim. Bu sefer kobay haline getirdiğimiz Chinook veritabanına yine Entity Framework 4.0 üzerinden bir WCF RIA Service yardımıyla erişiyoruz. Ancak Domain Service tipini üretirken OData(Open Data Protocol) desteği vereceğini belirtiyoruz. Bu durumda servisimizin çıktı olarak ürettiği Feed içeriğinin OData standartlarını destekleyen herhangibir ürün tarafından kullanılabileceğini belirtmiş oluyoruz. İstemci tarafında ise Excel 2010 Beta ürününe bir AddIn olarak gelen PowerPivot aracından yararlanıyoruz. Buna göre servisin sunduğu veri içeriğini, sadece bir iki hareketle Excel üzerinde kullanılabilir halde çekmiş oluyoruz. Söz konusu fonksiyonellik sayesinde veriyi ister ızgara görünümünde bırakabilir ister detaylı grafiklerini çıkartabiliriz. İşin güzel yanı, servisi dünyanın herhangibir noktasındaki bir sunucu üzerinde host edebilecek olmamız. Dolayısıyla Excel PowerPivot aracı söz konusu servise bağlanabildiği sürece verinin en güncel halini çekebiliyor olacak. E ne duruyorsunuz? NedirTv? sponsorluğundaki görsel dersimizi izlemeye buyrun.

Süre : 14:52

Boyut : 24.5 Mb

Download etmek veya izlemek için

Workflow Services - Custom Authorization

Pazartesi, 22 Mart 2010 13:30 by bsenyurt

Merhaba Arkadaşlar,

Aşçılık zevkli ama bir o kadarda zor bir zanaattır. Hatta bazen o kadar zor bir zanaat olur ki, aşcının aldığı maaşı pek çok yazılımcı iki yılda kazanamaz. Tabi bu tip aşçılar işin ehli olan kişilerdir. Heleki tek bir mutfak değilde dünya mutfağının seçkin olanlarına ait becerileri bulunanlara paha biçilemez. Türk Mutfağından Japon mutfağına, Meksika yemeklerinden İtalyan spesiyallerine, Fransız tatlılarından Okyanus deniz ürünlerine ve daha nicelerine...Tabi bir aşçı için olmassa olmazlardan biriside yemeği için gerekli olan malzemelerin kalitesidir. Kaliteli zeytinyağı, hamur ve baharat ile yapılan spagettinin, kalitesiz olanlar ile yapılanı arasında dağlar kadar fark olabilir. Spagetti demişken bu günkü yazımızda neler yapacağımıza da bir bakalım dilerseniz. Aşçı olarak bu gün elimizde zor bir tarif var. Malzemelerimiz belli ama pişecek olan yemeğin yapımı biraz zahmetli. Haydi gelin hiç vakit kaybetmeden önlüğümüzü takıp klavyenin başına geçelim.Wink

Bu yazımızda .Net Framework 4.0 tarafında geliştireceğimiz Workflow Service' lerde yetkilendirme işlemini nasıl sağlayabileceğimizi görmeye çalışacağız. Ne yazık ki Authorization işlemini kolaylaştırmak adına hazır bir yapı mevcut değil. Bu nedenle biraz kodlama yapmamız ve çalışma zamanının işleyişine bu şekilde müdahale etmemiz gerekiyor. Hatta yapacağımız özelleştirme öylesine etkili olacak ki, aradan Doğrulamayı(Authentication) bile çıkaracağız farkına varmadan. Surprised Ama önce yemek için gerekli malzemelerimizin neler olduğuna bir bakalım.

  • Bir adet Workflow Service.
  • Bir adet konfigurasyon dosyası(Web.config).
  • System.IdentityModel.dll referansı.
  • ServiceAuthorizationManager türevli bir sınıf.
  • Windows üzerinde tanımlanmış roller ve bu roller içerisinde yer alan kullanıcılar.

Tabiki malzemeleri tedarik etmek yeterli değil. Birde tarifi bilmek lazım Wink Öncelikli olarak yetkilendirme işlemini üstelenen bir sınıf yazmamız gerekiyor. Çok doğal olarak bu sınıfın Workflow Service çalışma zamanı tarafından değerlendirilebilmesi için konfigurasyon dosyası üzerinde de gerekli düzenlemeleri yapmalıyız. Sonrasında ise işi istemci tarafından gelen taleplere bırakıyor olacağız. İşe ilk olarak aşağıdaki gibi bir Workflow Service projemiz olduğunu varsayarak başlayalım.

Calculus.xamlx içeriğimiz ise aşağıdaki gibidir;(Sadece Sequence elementi içeriği verilmiştir)

<p:Sequence DisplayName="Sequential Service" sad:XamlDebuggerXmlReader.FileName="D:\Projects\Workflow Foundation 4.0\UsingCustomAuthorization\UsingCustomAuthorization\CalculusService.xamlx" sap:VirtualizedContainerService.HintSize="277,336">
    <p:Sequence.Variables>
      <p:Variable x:TypeArguments="CorrelationHandle" Name="handle" />
      <p:Variable x:TypeArguments="x:Int32" Name="X" />
      <p:Variable x:TypeArguments="x:Int32" Name="Y" />
      <p:Variable x:TypeArguments="x:Int32" Name="Sum" />
    </p:Sequence.Variables>
    <sap:WorkflowViewStateService.ViewState>
      <scg3:Dictionary x:TypeArguments="x:String, x:Object">
        <x:Boolean x:Key="IsExpanded">True</x:Boolean>
      </scg3:Dictionary>
    </sap:WorkflowViewStateService.ViewState>
    <Receive x:Name="__ReferenceID0" CanCreateInstance="True" DisplayName="ReceiveRequest" sap:VirtualizedContainerService.HintSize="255,86" OperationName="SumOp" ServiceContractName="p1:IService">
      <Receive.CorrelatesOn>
        <MessageQuerySet />
      </Receive.CorrelatesOn>
      <Receive.CorrelationInitializers>
        <RequestReplyCorrelationInitializer CorrelationHandle="[handle]" />
      </Receive.CorrelationInitializers>
      <ReceiveParametersContent>
        <p:OutArgument x:TypeArguments="x:Int32" x:Key="XValue">[X]</p:OutArgument>
        <p:OutArgument x:TypeArguments="x:Int32" x:Key="YValue">[Y]</p:OutArgument>
      </ReceiveParametersContent>
    </Receive>
    <SendReply Request="{x:Reference __ReferenceID0}" DisplayName="SendResponse" sap:VirtualizedContainerService.HintSize="255,86">
      <SendParametersContent>
        <p:InArgument x:TypeArguments="x:Int32" x:Key="SumResult">[X + Y]</p:InArgument>
      </SendParametersContent>
    </SendReply>
  </p:Sequence>

Aslında Calculus isimli Workflow Service içerisinde yer alan SumOp isimli operasyonun görevi çok basit ve bellidir. Int32 tipinden iki sayısal değerin toplanması ve sonucunun istemci tarafına geri döndürülmesi. Bizim hedefimiz sadece yetkisi olan kişilerin bu operasyonu çalıştırmasıdır. Bu durumda güvenlik ile ilişkili olarak yetki kontrolünün özel bir sınıf tarafından yapılması gerekmektedir. Söz konusu sınıf System.ServiceModel isim alanı(Namespace) altında yer alan ServiceAuthorizationManager tipinden türetilmelidir. İçeriğini ise çok sade olarak aşağıdaki gibi tasarlayabiliriz.

using System.Collections.Generic;
using System.Security.Principal;
using System.ServiceModel;

namespace UsingCustomAuthorization
{
    public class Authorizer
        : ServiceAuthorizationManager
    {
        protected override bool CheckAccessCore(OperationContext operationContext)
        {
            var authCtx = operationContext.ServiceSecurityContext.AuthorizationContext;
            var identities=(List<IIdentity>)authCtx.Properties["Identities"];

            foreach (var identity in identities)
            {
                var winIdentity = identity as WindowsIdentity;
                if (winIdentity != null)
                {
                    var winPrincipal = new WindowsPrincipal(winIdentity);
                    return winPrincipal.IsInRole("Administrators");
                }
            }

            return false;
        }
    }
}

Authorizer sınıfı içerisinde CheckAccessCore metodu ezilmiş ve parametre olarak gelen operationContext değişkeninden yararlanarak gerekli yetki kontrolü yapılmıştır. Buna göre Workflow Service' ten talepte bulunan bir Windows kullanıcısı, servisin host edildiği makinede tanımlı ise, Administrators rolünde olup olmadığı kontrol edilmekte ve buna göre geriye true veya false değeri döndürülmektedir. Tahmin edileceği üzere CheckAccessCore metodunun geriye false değer döndürmesi güvenlik hatasına yol açacaktır. Burada unutulmaması gereken bir noktayı da hatırlatmak yarar var. Örneğimizde konuyu son derece basit bir şekilde ele almak istediğimizden, doğrudan Administrator rolünün kontrolünü yapıp işin içinden sıyrılmaktayız. Oysaki yetki kontrolü için harici bir listeden yararlanılabilir. Bu liste web.config dosyasında appSettings kısmında tutulabileceği gibi bir Text dosya içerisinde veya veritabanı üzerindeki bir tabloda konuşlandırılabilir. Yinede varmak istediğimiz noktayı anladığınızı düşünerek devam ediyorum.

Sırada çalışma zamanı için Authorizer sınıfının yetki kontrolü amacıyla kullanılacağını bildirmemiz gerekiyor. Bunun için web.config dosyasını aşağıdaki şekilde düzenlememiz yeterli olacaktır.(Bu arada projemize System.IdentityModel.dll assembly' ını referans etmeyi unutmamalıyız. Aksi takdirde authCtx üzerinden hiç bir özelliğe erişemeyiz)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceAuthorization serviceAuthorizationManagerType="UsingCustomAuthorization.Authorizer, UsingCustomAuthorization"/>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add scheme="http" binding="wsHttpBinding"/>
    </protocolMapping>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

Dikkat edileceği üzere serviceAuthorization elementi ile yetkilendirme davranışını ele alacak Authorizer tipi belirlenmiştir. Ayrıca iletişimin güvenli olmasını sağlamak adına protocolMapping sekmesinde wsHttpBinding bağlayıcı tipinin kullanılacağı bildirilmiştir. İşte bu kadar. Wink Artık yemeğimizi orta ateşte 40 dakika kadar pişirip servis edebiliriz. Tabi servis etmeden önce tadına bakmak gerekmektedir. Nasıl mı?

Öncelikli olarak Administrator rolünde olan ve olmayan iki test kullanıcımız olduğunu düşünelim. Ben, örneği geliştirmekte olduğum makinede bu amaçla bsenyurt ve runi isimli iki kullanıcı oluşturdum. Bu kullanıcılardan bsenyurt Administrator rolünde iken runi User rolü içerisinde yer almakta. Dolayısıyla test sonuçlarımıza göre runi isimli kullanıcı talebi karşılığında Access Denied hata mesajını almalı. Bakalım gerçektende böylemi oldu?

WcfTestClient uygulamamızı Run As.. komutu yardımıyla önce bsenyurt kullanıcısı ile çalıştıralım. Eğer Asp.Net Developement Server' ı Visual Studio ortamına Attach' larsak CheckAccessCore metodu içeriğini de debug edebiliriz. Buna göre debug modunda aşağıdaki sonuçlar ile karşılaşırız.

Görüldüğü üzere bsenyurt kullanıcısı doğrulanmıştır. IsAuthenticated değerinin true olduğuna dikkat edelim. Şimdi WcfTestClient uygulamasının sonuç ekranına bakarsak toplama işleminin başarılı bir şekilde gerçekleştirildiğini görebiliriz.

Şimdi de WcfTestClient aracını Runi isimli kullanıcı ile çalıştıralım. Debug modda aşağıdaki sonuçlar ile karşılaşırız.

Tahmin edileceği üzere Runi isimli kullanıcı da doğrulanmıştır. Nitekim servisin çalıştırıldığı makine de tanımlı bir Windows kullanıcısıdır. Ancak WcfTestClient uygulaması üzerinden bir toplama işlemi talebinde bulunulduğunda hata mesajı ile karşılaşılacaktır.

Volaaaaa!!! Bu çok doğaldır. Nitekim Runi isimli kullanıcı Administrators grubuna dahil değildir ve bu yüzden yetki kontrolünden geçememiştir.

Yapmış olduğumuz bu çalışmaya göre bir Workflow Service' ini host ettiğimiz sunucu üzerindeki Windows kullanıcılarından ve dahil oldukları grup bilgilerinden yararlanarak az bir kodlama ile doğrulama ve yetkilendirme işlemlerini gerçekleştirebiliriz. Afiyet olsun Wink

UsingCustomAuthorization_RC.rar (17,67 kb) [Örnek Visual Studio 2010 Ultimate RC sürümü üzerinde geliştirilmiş ve test edilmiştir]

Screencast - Entity Framework, WCF RIA Services, Silverlight 4.0

Cuma, 19 Mart 2010 22:56 by bsenyurt

Merhaba Arkadaşlar,

Bildiğiniz üzere 2010 yılı Microsoft geliştiricileri açısından epey bir hareketli başladı. Aslında ayak sesleri 2008 yılındaki Profesyonel Geliştiriciler Konferansında(Microsoft PDC) duyulan pek çok ürünün artık nihai sürümlerinin çıkacağı günlere yaklaşıyoruz. Aldığımız duyumlar Nisan ayı içerisinde .Net Framework 4.0 ve Visual Studio 2010 tarafında Relase sürümlerinin en azından RTM sürümlerinin çıkacağı yönünde. 2008 ve belki de daha öncesinden beri süre gelen zaman içerisinde beni en çok şaşırtan ürünlerinden birisi de Silverlight. Daha dün gibi ilk versiyonunu hatırladığımız ürünün geçtiğimiz günlerde MIX2010 ile birlikte 4.0 sürümünün çıktığı duyruldu. Visual Studio 2010 Beta 2 ile kullanıp bakabildiğimiz ama RC sürümünde kullanılamayan sürüm artık kullanılabilir halde Wink Bunun için Silverlight resmi sitesinden gerekli kurulumları yapmanız yeterli olacaktır. Şu aşamada Visual Studio 2010 RC ve Visual Studio 2008 SP1 sürümlerinde ele alabiliyorıuz.

Silverlight tarafında beni en çok ilgilendiren konuların başında ise sunucu kaynaklarının istemci tarafından kullanılabilmesinde önemli bir rol üstelenen WCF RIA Service' ler gelmekte. Eski adıyla .NET RIA Service' lerin WCF Eco System içerisinde WCF RIA Service olarak anılmaya başlandığını biliyoruz. Daha öncesinde WCF RIA Service' ler ile ilişkili çeşitli blog yazılarım oldu ancak görsel anlatım ne denli güçlü olduğunu hepimiz gayet iyi biliyoruz. İşte bu felsefe ile ve NedirTv? desteğiyle hazırladığımız bu görsel dersimizde WCF RIA Service' lerinin kullanımına dair basit bir Hello World uygulaması geliştiriyor olacağız. Üstelik Domain Service tarafında Entity Framework 4.0 sağlayıcısından yararlanarak veri sunumunu gerçekleştireceğiz. İyi seyirler dilerim.

Boyut : 23.2 Mb

Süre : 15:32

Download Etmek veya İzlemek İçin

SilverlightApplication2.rar (2,37 mb) [Örnek Visual Studio 2010 RC sürümü üzerinde geliştirilmiş ve test edilmiştir]

Screencast - Windows Server AppFabric - Application Import ve Export İşlemleri

Perşembe, 18 Mart 2010 10:00 by bsenyurt

Merhaba Arkadaşlar,

Özellikle HTTP bazlı servis uygulamalarının geliştirilmesi sırasında göz önüne alınması gereken önemli noktaların başında IIS(Internet Information Services) üzerine yapılan dağıtım prosedürleri gelmektedir. Geliştirme sürecinde genellikle Asp.Net Development Server gibi sanal sunucular üzerinden çalıştırılan servislerin önce yerel IIS ortamından yayınlanıp test edilmeleri yaygındır. Sonrasında bir UAT(User Acceptance Test) makinesi üzerinde yer alan IIS sunucuna dağıtımları yapılarak söz konusu testlerin tekrar edilmesi sağlanır. Eğer herhangibir sorun yoksa, çoğunlukla UAT makinesi ile bire bir aynı olan Production makinesine taşınması işlemi gerçekleştirilir.

Günümüzde servis tabanlı uygulamalar pek çok büyük çaplı projede baş rolde yer almaktadır. Bu nedenle servislerin IIS gibi ortamlar üzerine yayınlanmalarının, izlenmelerinin öneminin daha da arttığı gözlemlenmektedir. Özellikle IT çevresinde yer alan ekiplerin, IIS ortamına dağıtılacak servisler ile ilişkili olarak daha çok yönetimsel araca sahip olmaları önemlidir. Bu noktada bilinen kod adı Dublin olan Windows Server AppFabric' in getirdiği önemli yenilikler bulunmaktadır. İşte bu görsel dersimizde söz konusu yeniliklerden birisini daha incelemeye çalışıyor olacağız. Çok basit olarak WCF servislerinin IIS üzerine bir Deployment Package haline dönüştürüldükten sonra Import edilmesi ve IIS üzerinde var olan bir WCF Servis Uygulamasının dış ortama paketlenerek sunulması(Export Application) işlemlerine göz atmaya çalışacağız. Keyifli seyirler dilerim.

Süre : 22:02

Boyut : 37.4 Mb

İzlemek veya download etmek için