Elazığ Fırat Üniversitesi Ineta Etkinliği

2. Mayıs 2012

Ineta olarak 4 Mayıs Cuma Günü Elazığ'da Fırat Üniversitesi'ndeyiz.

Dynamics CRM ve C# ağırlıklı olacak seminerimize katılabilecek durumda olan herkesi bekleriz.

, , , , , ,

Asp.Net Yazılımcı İş İlanı

1. Ocak 2010

Firmamızın ekibine yeni yazılımcılar katmak istiyoruz. Pozisyona kabul edilecek arkadaşlar direkt bana bağlı olarak çalışacaklar ve benden Dynamics CRM ve Dynamics Mimarisine özgü programlama tekniklerini öğreneceklerdir(Javascript, Workflow ve Plugin dizayn edip kodlama gibi). Başta proje içerisinde verilen görevi yerine getirme sorumluluğu daha sonra ise projeyi komple ele alıp bitirebilme yetenekleri kişiye kazandırılacaktır. Kısacası ekibimize katacağımız kişiler Dynamics CRM projelerinde ilk başta yazılımcı daha sonra ise danışman olarak yetiştirilecektir. Bu yüzden başvuracak adayın yeniliklere adapte olabilen, hızlı öğrenen, kendine her ortamda güvenen, yükselme hedefi olan nitelikte bir kişi olması gerekmektedir. Tabii ki okuduğunu anlayabilecek kadar ve karşılaştığı problemleri internette arayabilecek kadar İngilizce bilgisi de gerekmektedir.

İlerleyen aşamalarda danışman statüsüne yükselmek isteyen arkadaşların müşteri ile diyaloga geçip istek, öneri ve sorunlarını anlayabilmesi ve bunlara ekibiyle birlikte çözüm üretmesi gerekmektedir. 

Bu bağlamda ASP.Net ve C#’ı bilen kişiler arıyoruz. Bunun yanı sıra Windows Forms, Windows Servisleri, MS Sql Server, XHTML, DOM, XML, CSS gibi teknolojilere yatkınlık da aramaktayız. Asp.Net ile en az 1 yıl bir firmada yazılım geliştirmiş adaylar kabul edilecektir. Bir firmada tam zamanlı yazılım geliştirme deneyimi olmayan arkadaşlar lütfen başvurmasın.

Şirketimiz Kadıköy Hasanpaşa’da Metrobüs hattının son durağında yer almaktadır.  Başvuracak adayların maaş beklenti aralıklarını da belirtmesi gerekmektedir. Maaş beklenti aralığı verilmeyen CV’ler dikkate alınmayacaktır.


Başvuracak adayların Cv’lerini baris.kanlica@omerd.com veya idil.oter@omerd.com adreslerine göndermeleri rica olunur.

Dynamics CRM , , , , , , ,

İş İlanı

22. Ağustos 2009

Hızla büyüyen firmamızın ekibine 3 adet yeni arkadaş katmak istiyoruz. Pozisyona kabul edilecek arkadaşlar direkt bana bağlı olarak çalışacaklar ve benden Dynamics CRM ve Dynamics Mimarisine özgü programlama tekniklerini öğreneceklerdir(Workflow ve Plugin dizayn edip kodlama gibi). Başta proje içerisinde verilen görevi yerine getirme sorumluluğu daha sonra ise projeyi komple ele alıp bitirebilme yetenekleri kişiye kazandırılacaktır. Kısacası ekibimize katacağımız kişiler Dynamics CRM projelerinde ilk başta yazılımcı daha sonra ise danışman olarak yetiştirilecektir. Bu yüzden başvuracak adayın yeniliklere adapte olabilen, hızlı öğrenen, kendine her ortamda güvenen, yükselme hedefi olan nitelikte bir kişi olması gerekmektedir. Tabii ki okuduğunu anlayabilecek kadar ve karşılaştığı problemleri internette arayabilecek kadar İngilizce bilgisi de gerekmektedir.

İlerleyen aşamalarda danışman statüsüne yükselmek isteyen arkadaşların müşteri ile diyaloga geçip istek, öneri ve sorunlarını anlayabilmesi ve bunlara ekibiyle birlikte çözüm üretmesi gerekmektedir. 

Bu bağlamda ASP.Net ve C#’ı bilen kişiler arıyoruz. Bunun yanı sıra Windows Servisleri, MS Sql Server,XHTML, DOM, XML, CSS gibi teknolojilere yatkınlık da aramaktayız.

Senior olarak başvuracak adayların askerliğini tamamlamış olması gerekmektedir. Junior adayların ise en az 2 yıl tecilli olması yeterlidir. 

Şirketimiz Kadıköy Hasanpaşa’da Metrobüs hattının son durağında yer almaktadır.  Başvuracak adayların maaş beklenti aralıklarını da belirtmesi gerekmektedir. Maaş beklenti aralığı verilmeyen CV’ler dikkate alınmayacaktır.


Başvuracak adayların Cv’lerini baris.kanlica@omerd.com veya idil.oter@omerd.com adreslerine göndermeleri rica olunur.

Dynamics CRM , , , , , , , , , , ,

Akbank C# Eğitimi

10. Nisan 2009

Akbank Bilgi İşlem ekibinden 2 gruba 4 hafta boyunca C# eğitimi verdim. Eğitim içeriği ise şöyleydi :

Programming with C#

Programming with the Microsoft .NET Framework

Developing Microsoft .NET Applications for Windows

Developing Microsoft ASP.NET Web Applications Using Visual Studio .NET

Eğitimden sadece 2. Grubun foroğrafı elime ulaştığından onu yayınlayabiliyorum sadece.

Güncel eğitim bilgisi bu adreste : http://www.cub-e.net/page/crm_egitim_referanslari.aspx

Eğitim referanslarımı eğitim bölümde bulabilirsiniz. Sorularınız ile ilgili Murat Manoğlu'yla irtibata geçebilirsiniz. 0216 450 0 331
murat.manoglu@omerd.com 

 

c# , , , , , , , ,

Windows Vista Kullanıcı Hesap Denetimi (UAC-User Account Control)

2. Ocak 2009

Windows Vista Kullanıcı Hesap Denetimi (UAC-User Account Control)

Birçok kişi Vista’ya gıcık olsa da ben Vista’yı gerçekten çok sevdim. Microsoft son zamanlarda hissedilir bir şekilde üzerinde durduğu kullanıcı güvenliği konusunun son halini Vista içerisinde bir program çalıştırırken ya da bir kopyalama işlemi yaparken sürekli karşımıza çıkan o meşhur güvenlik ekranından biliyoruz.  Windows her zaman kullanıcı dostu yapısıyla bilinirken birdenbire birçok son kullanıcı için problemli bir işletim sistemi oldu.

Peki neden Microsoft böyle bir şeye ihtiyaç duydu derseniz? Herkes Windows’un çok güvensiz olduğundan sürekli virüs bulaşmasından ya da Internet Explorer ile bilgisayarımızı ele geçiren (virüs,solucan,trojan...) gibi kötü niyetli yazılımlardan bahseder işte Microsoft da bu durumun farkında. Yani siz sistem üzerinde Administrator (tam yetkili kullanıcı) olarak çalıştığınızdan uygulamalarınızın da Administrator olarak çalışmakta ve herşeye erişmede tam yetkili olmaları durumundan kaynaklanmaktaydı. Vista ile işte bu değişti.

Bu durum Windows uygulaması geliştiren programcılar için de sıkıntılı durumlar yarattı. Artık istediğimiz dosya ya da klasöre yazma işlemini gerçekleştiremiyor, registry üzerinde işlem yapamıyor ya da Sistem üzerindeki WMI gibi arabirimlere bağlanamıyor olduk. Nedeni ise çok basit; çünkü geliştirdiğimiz uygulama, kullanıcı sistem Administrator’u olsa bile  Administrator haklarına sahip değil.

UAC Nedir?

Peki Vista bu işi nasıl yönetiyor diyorsanız; cevap, Vista üzerinde geliştirilen Kullanıcı Hakları Denetimi (UAC – User Account Control) isimli mimari. Kullanıcı Hesaplarını Denetimi (UAC); aynı kullanıcı altında çalışan yazılımların farklı haklar ile çalışabilmesini sağlıyor yani kullanıcıların bir program çalıştırmaya kalktıkları zaman bir uyarı diyaloğu göstererek programa doğrudan girişi engelliyor. Mesela bir program yönetici (administrator) hakları gerektiriyorsa o program çalışmadan önce sizden o programa administrator hakkı verip vermeyeceğinizi soruyor. Kullanıcısı hakkın verilmesini  onaylarsa program yönetici olarak çalışıyor. Windows’ un kendi uygulamaları için de bu durum  geçerli, mesela sistem dosyalarını değiştirmek isterseniz Windows Explorer sizden yönetici onayı istiyor.

Kısacası düşük kullanıcı hakları (LUA-Least Priviliged User Account) ile yazılımları çalıştırmak güvenliğin temel noktalarından biri. Microsoft ise bu şekilde bilgisayarın güvenliğinin en üst düzeye çıktığını ve yöneticiler dışındaki kişilerin bilgisayarda değişiklikler yapmalarının engellediğini savunuyor.

Integrity Levels

UAC’ nin en kritik özelliklerinden biri Integrity Levels. Vista’ da uygulamalar dört farklı seviyede çalışıyorlar (düşükten yükseğe)

  1. Low – Potected Mode
  2. Medium – LUA
  3. High - Elevated
  4. System

Her Integrity Level’in objeye göre hakları olabilir (obje çalışan bir uygulama ya da normal bir dosya olabilir).

Normal yazılımlar özel olarak belirtilmedikçe Medium seviyede çalışıyorlar;

  • High, özel olarak UAC penceresi ile yetkilendirilmiş yazılımlar.
  • System, sistem uygulamaları.

Dolayısıyla bu integerity seviyeleri sadece çalışan programlar ile ilgili değil aynı zamanda dosya sistemindeki erişim haklarıyla da ilgili. Eğer okunmaya çalışan obje dosya sistemindeki bir obje ise çalışan uygulama sadece kendi seviyesindeki ve altında objeleri okuyabilir.

(IE genelde sorun çıkarmaya müsait olduğu için en düşük haklar olan Low – Protected Mode ile çalışıyor.)

Sanallaştırma (Virtualization)

Vista’dan önce (hatta Vista’dan sonra bile) birçok uygulama “C:\windows” ya da en azından kendisinin kurulu olduğu örneğin “c:\Program Files\herhangi bir uygulama\ayarlar.ini” dosyasını okumak hatta buraya yazmak isteyebilir ve sistem işleyişi gereği kullanıcının buralara yazma yetkisi olmayabilir.

Bu durumda Vista sanal dosya ve sanal registry kullanarak orjinal dosya ve registry sistemini korumaya alıyor. Dolayısıyla eğer bir program yönetici yetkileri ilebir şeyler yazmaya çalışırsa Vista bunu otomatik olarak aktif kullanıcının profili altındaki klasöre ve registery' ye yönlendiriyor. Bu sayede bir dizi program hata almaktan kurtuluyor.

UAC File Virtualization Filter Driver (%SystemRoot%\System32\Drivers\Luafv.sys) dosya sistemi üzerindeki bu sanallaştırma işlemini yöneten mimari.

Kısacası bir uygulama “C:\Program Files\uygulama klasörü\ayarlar.ini” isimli bir dosyaya erişmek istediğinde “C:\Users\Username\AppData\Local\VirtualStore\Program Files\uygulama klasörü\ayarlar.ini” dosyasına erişiyor olacak. Eğer aynı uygulama registry üzerindeki “HKEY_LOCAL_MACHINE\Software\uygulama adı\”  düğümüne bir değer yazmak istiyorsa otomatik olarak “HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\Software\uygulama adı” ya da “HKEY_USERS\UserSID_Classes\VirtualStore\Machine\Software\uygulama adı” düğümlerinden birine veri yazıyor olacak. Uygulama böylece bir sandbox’un içinde çalışıyor olacak.

Şimdi bu konulara bir uygulama ile sistemin bizi nasıl sandbox’a alıp sanallaştırdığını görelim.

1.       Visual Studio 2008’i açıp VistaVirtualizationTester isimli bir console uygulaması açalım.

2.       Aşağıdaki kodları uygulamamıza ekleyelim; 

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

using System.IO;

namespace VistaVirtualizationTester
{
   
class Program
   
{
       
static void Main(string[] args)
       
{
           
//dönüş noktamız
       
tryagain:
           
try
           
{
               
//yazılacak metin
               
string lines = "birkaç satır birşeyler \r\ndenemeye değer bir uygulama \r\nBarış KANLICA."

                //yazma işlemi
                string localPath = "c:\\windows";
              
//string localPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
               
System.IO.StreamWriter file = new System.IO.StreamWriter( localPath + "\\test.txt");
               file.WriteLine(lines);
                file.Close(); 

                //ekrana gerçekleşen işlemi yaz
               
Console.WriteLine("Yazma işlemi başarıyla sonuçlandı.");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                //ekrana hatayı yazdır
                Console.WriteLine("Yazma işlemi sırasında hata oluştuı.");
                Console.WriteLine(ex.Message);
                Console.ReadLine();
                //tekrar dene emri
                goto tryagain;
            }
        }
    }
}

3.       Solution üzerinde sağ tuşa basıp Properties ekranını açalım 

4.       Icon and Manifest kısmı altında “Create application witout manifest” ‘i seçiyoruz. 

Böylece manifest dosyası olmayan bir uygulama yaratmış olduk.  (Manifest nedir diyenler için açıklama da yapalım. Manifest içerisinde assembly metadata'larını bulunduran bölümdür. Asembly adı, versiyonu, başka Assembly'lere olan referanslar gibi bilgilerin tamamına metadata denir. Bu bilgilerin oluşturduğu kümeye Manifest denilmektedir.) Bu yaptığımız adımlar ile biz manifest bölümü olmayan bir assembly yaratmış olduk.

Uygulamamız ise “c:\Windows” içerisine birkaç satır dosya yazmayı amaçlamaktadır. Eğer hata oluşursa kullanıcıya bunu göstermekte ve klavye girdisi beklemektedir. Kullanıcı klavyede enter tuşuna basarsa tekrar aynı kodu çalıştırıp yazma işlemini tekrar deneyecektir.

Uygulamayı bu haliyle çalıştırdığınızda (Uygulamayı Visual Studio içerisinden değil build edilen yerden çalıştırılım.) “C:\Users\<kullanıcı adı>\AppData\Local\VirtualStore\Windows” içerisine test.txt isimli bir dosya oluşturduğunu göreceksiniz. Böylece sanallaştırma ile ilgili yukarıda anlattıklarımı örneklemiş oldum.

Peki bir uygulamanın sanal olarak çalıştığını nasıl anlarım diyebiilirsiniz hatta bir adım daha öteye gidip bir uygulamayı nasıl sanallaştırma içerisine sokabilirim diyebilirsiniz. Bu durumda görev yöneticisi (task manager) devreye giriyor. Task Manager açık iken İşlemler (Process) ekranında Görünüm (View)->Sütun Seç (Select Columns)->Sanallaştırma (Virtualization) sütununu açabilirsiniz. Bu sütunda bir uygulamanın hangi modda çalıştığını görebilirsiniz.

Bizim uygulamamızı tekrar çalıştırdığımızda uygulamanın virtualization modunun enabled olduğunu göreceksiniz. Şimdi bir adım daha ileri gidelim ve uygulammızın manifest durumunu tekrar eski haline alalım yani “Embed manifest with default settings” seçeneğini bu sefer seçelim. Ve uygulamamızı çalıştıralım. (Uygulamayı Visual Studio içerisinden değil build edilen yerden çalıştırılım.)  Çalıştırdığımızda uygulamanın yazamadığını ve hata verdiğini göreceksiniz.

Uygulamamızın Virtaualization kısmının Disabled olduğunu görüyoruz. Peki nasıl aktif hale getirebiliriz ? Çok basit task manager içerisinde uygulama üzerinde sağ tuşa bastığımızda Virtualization’ı tıklarsak bir uyrarı gelecek bu uyarıya evet dersek uygulamamız sanallaştırılmış moda dönecek.

Bu işlemden sonra uygulamamızın üzerine gelip enter’a basarsanız yazma işleminin gerçekleştiğini görebilirsiniz. Biraz daha derine inerek Sanallaştırmanın geçerli olduğu ve olmadığı durumlara da bir göz atalım,

Sanallaştırmanın geçerli olduğu durumlar:

  • 32 bit interaktif işlemler
  • Administrator haklarıyla yazılabilir dosya/klasör ve registry keys

Sanallaştırmanın geçerli olmadığı durumlar:

  • 64 bit işlemler
  • İnteraktif olmayan işlemler
  • İmpersonate kaynaklı işlemler
  • Kernel mod çağrıları
  • requestedExecutionLevel yetkisiyle çalıştırma

UAC ile Yetki İstemek

Bütün bu adımlardan sonra size bir de app.manifest dosyamızda yapacağımız küçük ama etkili bir değişiklik ile uygulamamızın kullanıcıdan nasıl yetki isteyeceğini göstereceğim.

Şunu unutmamak gerekir ki eğer bu yetkilendirme gerekli değilse gerçekten kullanmayın eğer bir klasöre ya da registry’e bir şeyler yazmanız gerekiyor ise Vista’nın size yazma okuma yetkisi verdiği yerleri kullanabilirsiniz. Örnek olarak yönetici yetkisi olmadan dosya yazmak veya okumak için en mantıklı yol Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) gibi komutlar kullanarak kullanıcının yazma yetkisinin olacağı bir klasörü kullanmak.

Ama yok uygulamanızın illa ki bu haklara ihtiyacı varsa mesela IIS üzerinde işlem yapan bir uygulama ya da sistem üzerinden WMI sorgusu çekmeniz gerekiyorsa o zaman app.manifest dosyamızı değiştirmemiz gerekli.

Burada Visual Basic kullanıcıları için bir güzellik yapmış Microsoft ve Visual Studio’nun içerisine bir kısayol gömmüş. 

VB Solution’ınızın üzerinde sağ tuşa basar ve Properties’e gelirseniz;

 

 

View UAC Settings isimli bir düğme bulacaksınız bu düğmeye tıkladığınızda ise;

 

 

App.manifest dosyanızın geldiğini göreceksiniz. 

C# kullananlar ise farklı bir yol izlemek zorunda. Yine solution üzerinde sağ tuşa tıklayarak bu sefer “ add->new item” demelisiniz açılan pencereden Application Manifest File dosyanızı seçip projenize ekleyebilirsiniz.

App.manifest dosyamızın içeriği şöyledir; 

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <
requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC Manifest Options
            If you want to change the Windows User Account Control level replace the
            requestedExecutionLevel node with one of the following.

        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

            If you want to utilize File and Registry Virtualization for backward
            compatibility then delete the requestedExecutionLevel node.
       
-->
        <
requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
    </
security>
  </
trustInfo>
</asmv1:assembly>

“requestedExecutionLevel” seviyesinin standart olarak “asInvoker” olarak ayarlı olduğu görebilirsiniz.

Değer

Açıklama

asInvoker

Uygulama en düşük yetki seviyesinde çalışır.

highestAvailable

Uygulama kendisini çağıran kullanıcıdan daha yüksek yetki ile çalışır ve mevcut kullanıcıdan yetki ister.

requireAdministrator

Uygulama administrator yetkisiyle çalışır ve mevcut kullanıcıdan yetki ister.

Bu durumda bizim asInvoker yazan yere requireAdministrator yazmamız gerekmekte. Bu değişikliği yapıp projeyi Visual Studio içerisinden çalıştırmak istediğimizde Visual Studio da yönetici haklarını bizden isteyecektir. “Restart under different credentials”’ı seçmemiz gerekmekte.

Ve Visual Studio kapanıp yeniden açılacaktır. Açıldığından onun da yönetici moduyla çıldığını görürüz.

Hatta uygulamamızın klasörüne gidip baktığımızda ise uygulamızın simgesinin altına Shield işaretinin geldiğini görebiliriz. 

Uygulamızı her çalıştırmak istediğimizde bizden yetki isteyecek. Eğer kullanıcı onaylarsa uygulamamız yönetici (administrator) haklarıyla çalışacak ve sistem üzerinde tam yetkili olacaktır. Tam bu noktada şu açıklamayı yapmak ta sanıyorum yerinde olacaktır. Eğer Windows’ un nasıl çalıştığı hakkında detaylı bilginiz varsa (en azından Windows’un mesaj tabanlı bir işletim sistemi olduğunu biliyorsanız) Windows’ un iç mesajlarını kullanarak başka yazılımlara istek göndermek ve bu sayede haklarınızı yükseltmek (privilige escelation) şeklinde saldırıya uğradığını da duymuşsunuzdur. (Shatter Saldırıları)

Bu nedenle UAC penceresi ayrı bir masaüstü olan “Session0” da çalışıyor. Bu bağlamda masaüstleri tamamen ayrı durumdalar ve birbirlerine windows mesajları ile mesaj gönderememektedirler. (Hatta arkadaki siyah plan bile aslında gerçek değil, isteğin yapıldığı anda arka planın kaydedilmiş bir resmi.)

UAC’nin devreye giridği işlemlerin tam listesi ise şöyle; 

·         Program Vista’ nın Uyumluluk listesindeyse

·         Program manifest dosyasında bunu belirtirse 

·         API ile bu istek yapılırsa

·         Kullanıcı özel olarak bir programın “Run As Administrator” ile çalıştırırsa (Bu noktada yine küçük bir bilgi vereyim; eğer çok sık kullandığınız bir program var ise üzerinde sağ tuşa basıp Uyumluluk (Compatibility) sekmesi üzerinde “Bu programı yönetici yetkisiyle çalıştır” (run this program as an administrator) checkini işaretlerseniz artık sizden yetki istemeyecek otomatik olarak yönetici haklarıyla çalıştıracaktır)

·         Vista bir programın “installer” programı olduğunu düşünürse.

UAC’yi Devre Dışı Bırakmak ya da Tekrar Aktif Hale Getirmek

UAC devre dışı da bırakılabilen bir yapı ve bir Vista üzerinde 2 şekilde devre dışı bırakabilirsiniz;

1.       Denetim Masasından (Control Panel)

a.       Denetim Masası içerisinde Kullanıcı Hesapları (User Accounts) altından

b.      Kullanıcı Hesapları Denetimi’ni aç ya da kapat (Turn User Account Control on or off) düğmesine tıklayınca karşınıza bir ayar ekranı açılır.

c.       Buradaki tiki kaldırarak kapatabilir ya da açabilirsiniz.

2.       Komut Satırı üzerinden (Command Prompt) 

a.       Aktive etmek

C:\Windows\System32\cmd.exe /k %windir%\System32\reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 1 /f

b.      Kapatmak

C:\Windows\System32\cmd.exe /k %windir%\System32\reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f

 

Windows 7’de Nasıl Olacak

Gelecek senenin sonlarında çıkarılması planlanan yeni işletim sistemi Windows 7’de de bu uygulamayı devam ettirilecek. Tabi arabirimde köklü değişiklikler yapılacak bu sefer devam uyarıların sıklığı kullanıcıların kendisi tarafından ayarlanabilecekmiş hatta açılması istenen programla ilgili açıklayıcı sorular sorulacakmış.

2007'nin ağustos ayından 2008'in ağustos ayına kadar "yönetici olarak çalıştırma" gerektiren programlar tam %75 oranında azalmış. Yani, yazılım firmaları Vista ile beraber “Microsoft Standartlarında” güvenli yazılımlar üretmeye başlamışlar.

Son Sözler

Konuyu toparlayacak olursak. Windows 7’de de bu uygulama süreceğine göre artık yazılımlarımızı buna göre geliştirmeye alışmamız gerekiyor. Microsoft bence bu konuda da çok haklı çünkü herkes sistem üzerinde istediği gibi davranırsa Windows sürekli problem çıkartan bir işletim sistemi olur ve bu zamana kadar da öyle oldu zaten. Eğer gerçekten yönetici haklarına ihtiyacınız yoksa sanallaştırmanın bize sunduğu ile yetinip yolumuza devam edelim ve sistemi stabil kılan uygulamalar yazalım. Bir makale de burada biter hepiniz hoşçakalın.

Diğer Kaynaklar

  • Programların hangi integrity seviyesinde çalıştığını görebilmek için AccessChk
  • Dosya sisteminde bu hakları görmek için icacls
  • Windows Engineering Blog için tıklayınız
  • Technet Magazinden konuyla ilgili bir makale için tıklayınız

Barış KANLICA
Yazılım Uzmanı – Software Specialist

brsk@e-kolay.net
www.cub-e.net
forum.cub-e.net

Windows Engineering , , , , , , , ,

Core Entity mi Dynamic Entity mi? ( 2.Bölüm Veri Yazma)

29. Ocak 2008
Dynamic Entity'ler ile ilgili birinci makalemiz veri sorgulama idi. İkinci makalede ise veri yazma yöntemlerini göreceğiz. Burada dynamic entity'i anlatmadan önce core entity yöntemiyle veri yazmaya değineceğim. Böylece aradaki farkları görmemiz daha kolay olacaktır.

Konuyu hatırarsak; bir web servisini add web reference diyerek projenize dahil ettiğinizde visual studio arka tarafta bir bir class mimarisi oluşturur ve siz o mimariyi kullanırsınız. Eğer core enitity kullanırsanız, bu class özelleştirme nedeniyle her firmada farklı bir hal alabilir ve kodu yeniden derlemize neden olur. İşte bundan kurtularak çalışma zamanında nesneler yaratıp bunlara değer atamayı göreceğiz.

Hatırlarsanız bir örnek uygulamamız vardı. Senaryo şöyle idi; bir web sitemiz olacak ve bu web sitemize insanlar ad,soyad,e-mail,ilçe ve il bilgilerini yazarak kayıt olacaklar. Fakat biz forma girilen e-mail'i kullanarak veritabanımızda bu kişinin kayıtlı olup olmadığını kontrol edeceğiz eğer yoksa müşteri adayı (lead) olarak bu kişiyi Microsoft Dynamics CRM'e kaydedeceğiz.

Kaydet düğmesinin arkasında aşağıdaki kod yer almakta.
Mail adresinin yazılıp yazılmadığına bakıyoruz. Eğer yazıldı ise
dynamicRetrieve metodu ile bu mailinde birilerinin sistemde olup olmadığına bakıyoruz.



/// <summary>
///
Kaydet Dugmesi Click Olayi
/// </summary>
///
<param name="sender"></param>
///
<param name="e"></param>
protected void btnSave_Click(object sender, EventArgs e)
{
   
if (txtMail.Text != "")
    {
       
if (!dynamicRetrieve(txtMail.Text))
        {
           
if (coreCreate())
                lblMessage.Text =
"başarıyla oluşturuldu";
           
if (dynamicCreate())
                lblMessage.Text =
"başarıyla oluşturuldu";
        }
    }
}

Birinci makalede e-mail adresinden kontrol etmeyi gördük. Kontrol sonucunda e-mail adresinin sistemde bulunmadığını ve oluşturmamız gerektiğini düşünelim.


1.Core Entity

Burada önemli 3 adım bulunmakta.
1. web servisteki lead sınıfını çağırıyoruz
        lead myLead = new lead();
2. class içerisindeki proprty'e ilgili değeri atıyoruz
        myLead.firstname = txtName.Text.ToString();
3. içersisini veri ile doldurduğumuz class'ı servise oluşturması için veriyoruz.
        MyService.Create(myLead);

/// <summary>
///
coreCreate metdodu Core Entity kavramiyla lead olusturmayi bize gosterecek
/// </summary>
private bool coreCreate()
{
   
try
   
{
       
// CRM Servis'ini cagiriyoruz
       
CrmService MyService = service();
       
//lead sınıfımız aryoruz ve üretiyoruz.
       
lead myLead = new lead();
       
       
//textbox'ın değer içerip içermediğine bakıyoruz.
       
if (txtName.Text != string.Empty)
           
//eğer değer içeriyor ise class içerisindeki ilgili attribute a değerini veriyoruz.
           
myLead.firstname = txtName.Text.ToString();
       
if (txtSurname.Text != string.Empty)
            myLead.lastname = txtSurname.Text.ToString();
       
if (txtMail.Text != string.Empty)
            myLead.emailaddress1 = txtMail.Text.ToString();
       
if (txtState.Text != string.Empty)
            myLead.address1_stateorprovince = txtState.Text.ToString();
       
if (txtCity.Text != string.Empty)
            myLead.address1_city = txtCity.Text.ToString();
       

        //Son olarak da değer atamalarımız bitince servisin Create metodu ile
        //lead imizi oluşturuyoruz.
       
MyService.Create(myLead);
       
return true;
    }
   
catch (Exception ex)
    {
        HandleException(ex);

        return false;
    }
}

2. Dynamic Entity

Eğer bu oluşturma işlemini dynamic entity özelliğini kullanarak yapmış olsaydık kod bu sefer aşağıdaki gibi olacaktı.
Ama önce ne yaptığımızı anlatalım;

1. CRM Servis'ini cagiriyoruz. Burada service(); benim yazdığım bir metod ve crm servisini oluşturuyor.

       
CrmService MyService = service();
2. DynamicEntity nesnesini yaratyoruz

        DynamicEntity leadEntity = new DynamicEntity();
3. Entity ismini veriyoruz.

       
leadEntity.Name = EntityName.lead.ToString();
4. Eger deger iceriyorsa; Property nesnemizi cagiriyoruz ve adın ve degeri veriyoruz. Boylece calisma aninda bir class'in icerisindeki bir nesneye deger vermis oluyoruz.

           
StringProperty firstname = new StringProperty();
            firstname.Name =
"firstname";
            firstname.Value = txtName.Text;

Tabii burada yeri gelmişken söz etmekte fayda var CRM sadece string türünde bir değişken biçimi ile çalışmıyor. Yukarıdaki örnek "StringProperty" classından bir değişken türeterek string oluşturmaya yarıyor. Diğer değişken türleri (sınıflar) ise aşağıdaki listede yer almakta;


Sınıf Adı Microsoft Dynamics CRM Attribute Türü
CrmBooleanProperty CrmBoolean
CrmDateTimeProperty CrmDateTime
CrmDecimalProperty CrmDecimal
CrmFloatProperty CrmFloat
CrmMoneyProperty CrmMoney
CrmNumberProperty CrmNumber
CustomerProperty Customer
DynamicEntity N/A
DynamicEntityArrayProperty N/A
EntityNameReferenceProperty EntityNameReference
KeyProperty Key
LookupProperty Lookup
OwnerProperty Owner
PicklistProperty Picklist
Property N/A
StateProperty State
StatusProperty Status
StringProperty String
UniqueIdentifierProperty UniqueIdentifier
N/A Internal

Memo

Virtual



///
<summary>
///
dynamicCreate metdodu Dynamic Entity kavramiyla lead olusturmayi bize gosterecek
/// </summary>
private bool dynamicCreate()
{
    try
   
{
       
// CRM Servis'ini cagiriyoruz
       
CrmService MyService = service();
   
       
// DynamicEntity nesnesini yaratyoruz
       
DynamicEntity leadEntity = new DynamicEntity();
       
// Entity ismini veriyoruz.
       
leadEntity.Name = EntityName.lead.ToString();
       
// Property'ler icin bir Array olusturuyoruz.
       
ArrayList arrProps = new ArrayList();
   
       
// Textbox deger iceriyor mu diye kontrol ediyoruz.
       
if (txtName.Text != string.Empty)
        {
           
// Eger deger iceriyorsa; Property nesnemizi cagiriyoruz ve
            // adn ve degeri veriyoruz. Boylece calisma aninda bir class'in
            // icerisindeki bir nesneye deger vermis oluyoruz.
           
StringProperty firstname = new StringProperty();
            firstname.Name =
"firstname";
            firstname.Value = txtName.Text;
            arrProps.Add(firstname);
        }
       
if (txtSurname.Text != string.Empty)
        {
           
StringProperty lastname = new StringProperty();
            lastname.Name =
"lastname";
            lastname.Value = txtSurname.Text;
            arrProps.Add(lastname);
        }
       
if (txtMail.Text != string.Empty)
        {
           
StringProperty mail = new StringProperty();
            mail.Name =
"emailaddress1";
            mail.Value = txtMail.Text;
            arrProps.Add(mail);

        }
       
if (txtState.Text != string.Empty)
        {
           
StringProperty state = new StringProperty();
            state.Name =
"address1_stateorprovince";
            state.Value = txtState.Text;
            arrProps.Add(state);
        }
       
if (txtCity.Text != string.Empty)
        {
           
StringProperty city = new StringProperty();
            city.Name =
"address1_city";
            city.Value = txtCity.Text;
            arrProps.Add(city);
        }
       
// Property'leri bir DynamicEntity'e teslim ediyoruz.
       
leadEntity.Properties = (Property[])arrProps.ToArray(typeof(Property));
       
       
// Ve final entity'imizi olusturmasi icin servise veriyoruz.
       
MyService.Create(leadEntity);
        return true;
    }
   
catch (Exception ex)
    {
        HandleException(ex);
   
    return false;
    }
}


Uygulamamızı çalıştırdığımızda aşağıdaki ekran görüntüsünü elde edeceğiz.



Bir makale daha burada biter. Hepiniz hoşçakalın.

Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net

 

Dynamics CRM , , , , , , , , , , , , ,

Core Entity mi Dynamic Entity mi? ( 1.Bölüm Veri Sorgulama)

29. Ocak 2008
Microsoft Dynamics CRM üzerinde program geliştiriren herkes veri yazarken ve veri okurken web servisinden faydalanmamız gerektiğini bilir. (Veri okurken ek olarak fetchxml ve filteredview da kullanılabilir)
 
Peki bu işlemler sırasında web servisindeki nesnelere nasıl erişirsirsiniz?

Peki CRM üzerinde çalışacak bir uygulama geliştirdiniz ve bu uygulama web servislerini kullanarak CRM üzerine veri yazan bir uygulama olsun. Amacınız bu uygulamayı CRM kullanan firmalara satarak çok para kazanmak. Ama her müşterideki özelleştirme (customization) birbirinden farklı olacağından web servisleri de birbirinden farklı olacak. Çünkü standart yöntemde web servisindeki bir sınıf türetilerek, türetilen sınıftaki nesnelere erişilir. Her firmada nesneler de birbirinden farklı olabilir.  Sonucunda uygulamanızı her müşteri için derleyecek misiniz?

Bu çok saçma ve çok yorucu olurdu. Bu durumda bize kod zamanında değil çalışma zamanında nesneleri yönetmemizi sağlayacak bir yapıya ihtiyacımız var. Yani çalışma zamanında nesneler yaratıp bunlara değer atamalıyız.

İşte CRM içerisinde bu düşünülmüş, Core Entity yani standart nesne yönetimini yerine Dynamic Entity modeli ile nesneleri çalışma zamanında oluşturabilir ve yönetebiliriz. Dynamic Entity yöntemiyle veri sorgulayabilir ve veri yazabiliriz. Sırasıyla bu ikisini göreceğiz.

Konuyu örnek uygulamamızda irdeleyelim. Örnek uygulamamız için şöyle bir senaryo düşünelim. Bir web sitemiz olacak ve bu web sitemize insanlar ad,soyad,e-mail,ilçe ve il bilgilerini yazarak kayıt olacaklar. Fakat biz forma girilen e-mail'i kullanarak veritabanımızda bu kişinin kayıtlı olup olmadığını kontrol edeceğiz eğer yoksa müşteri adayı (lead) olarak bu kişiyi CRM'e kaydedeceğiz.




Kaydet düğmesinin arkasında aşağıdaki kod yer almakta.
Mail adresinin yazılıp yazılmadığına bakıyoruz. Eğer yazıldı ise
dynamicRetrieve metodu ile bu mailinde birilerinin sistemde olup olmadığına bakıyoruz.

/// <summary>
///
Kaydet Dugmesi Click Olayi
/// </summary>
///
<param name="sender"></param>
///
<param name="e"></param>
protected void btnSave_Click(object sender, EventArgs e)
{
   
if (txtMail.Text != "")
    {
       
if (!dynamicRetrieve(txtMail.Text))
        {
           
if (coreCreate())
                lblMessage.Text =
"başarıyla oluşturuldu";
           
if (dynamicCreate())
                lblMessage.Text =
"başarıyla oluşturuldu";
        }
    }

}

Dynamic Entity yönetemiyle veri sorgulamayı göreceğiz ilk önce. (Core entity ve diğer veri sorgulama yöntemleri ile ilgili olarak 3 makalelik bir yazı dizisi yayınlamıştım hatırlarsanız o yüzden bu makalede bu konulara girmeyeceğim.)

İlk önce kodu inceleyelim.


1. query nesnemizi oluşturuyoruz

        QueryByAttribute query = new QueryByAttribute();

2. hangi entity üzerinde sorgulama yapacağımızı söylüyoruz.

        query.EntityName =
EntityName.lead.ToString();

3. sorgulama sonucunda hangi alanları geri istiyoruz bunu söylüyoruz

       
ColumnSet cs = new ColumnSet();
        cs.Attributes =
new string[] { "firstname","lastname","address1_city" };
        query.ColumnSet = cs;

 4. koşulumuzu veriyoruz.
        query.Attributes =
new string[] { "emailaddress1" };
        query.Values =
new object[] { mail };

        Aslında buraya kadar ( " select firstname","lastname","address1_city from filteredlead where emailaddress1 = '"+ mail +"' ") dedik. Ama servis kullanarak bunu demek daha zahmetli.

5. servisimizi çağırıyoruz. Burada service(); benim oluşturduğum bir metod. CRM 3.0 ve CRM 4.0 arasında servise bağlanmakta farklılıklar var. Bunu daha önceki bir makalemde anlattığım için burada anlatmıyorum.

       
CrmService MyService = service();

6. işte can alıcı nokta burası geriye core entity değil dynamic entity istediğimizi söylüyoruz.
        retrieved.ReturnDynamicEntities =
true;

7. gelen sınıfı DynamicEntity türüne çeviriyoruz.
           
DynamicEntity entity = (DynamicEntity)responsed.BusinessEntityCollection.BusinessEntities[0];

8. işte ikinci can alıcı nokta burası. gelen DynamicEntity içinden property leri birer birer çıkartıyoruz.
Gelen property inin Value attribute 'u içerisinde değer bulunmakta bunu set ediyoruz.
           
StringProperty property = (StringProperty)entity.Properties[i];
            firstname = property.Value;

Kodun tamamı aşağıdadır.

/// <summary>
///
dynamicRetrieve metdodu Dynamic Entity kavramiyla veri cekmeyi bize gosterecek
/// </summary>
private bool dynamicRetrieve(string mail)
{
   
try
   
{
        //query nesnemizi oluşturuyoruz
        QueryByAttribute query = new QueryByAttribute();

        //hangi entity üzerinde sorgulama yapacağımızı söylüyoruz.
        query.EntityName =
EntityName.lead.ToString();

        //sorgulama sonucunda hangi alanları geri istiyoruz bunu söylüyoruz
       
ColumnSet cs = new ColumnSet();
        cs.Attributes =
new string[] { "firstname","lastname","address1_city" };
        query.ColumnSet = cs;

        //koşulumuzu veriyoruz.
        query.Attributes =
new string[] { "emailaddress1" };
        query.Values =
new object[] { mail };

        //aslında buraya kadar ( " select firstname","lastname","address1_city from filteredlead where emailaddress1 = '"+ mail +"' ") dedik.

        //
servisimizi çağırıyoruz.
       
CrmService MyService = service();
       
RetrieveMultipleRequest retrieved = new RetrieveMultipleRequest();

        //işte can alıcı nokta burası geriye core entity değil dynamic entity istediğimizi söylüyoruz.
        retrieved.ReturnDynamicEntities =
true;
        retrieved.Query = query;
       
RetrieveMultipleResponse responsed = (RetrieveMultipleResponse)MyService.Execute(retrieved);
       
if (responsed != null && responsed.BusinessEntityCollection.BusinessEntities.Length > 0)
        {

   
        //gelen sınıfı DynamicEntity türüne çeviriyoruz.
           
DynamicEntity entity = (DynamicEntity)responsed.BusinessEntityCollection.BusinessEntities[0];
           
string firstname = "";
           
string lastname = "";
           
string city = "";
           
for (int i = 0; i < entity.Properties.Length; i++)
            {
               
if (entity.Properties[i].Name.ToLower() == "firstname")
                {
           
        //işte ikinci can alıcı nokta burası. gelen DynamicEntity içinden property leri birer birer çıkartıyoruz.
                    //gelen property inin Value attribute 'u içerisinde değer bulunmakta bunu set ediyoruz.
                   
StringProperty property = (StringProperty)entity.Properties[i];
                    firstname = property.Value;
                }
               
if (entity.Properties[i].Name.ToLower() == "lastname")
                {
                   
StringProperty property = (StringProperty)entity.Properties[i];
                    lastname = property.Value;
                }
               
if (entity.Properties[i].Name.ToLower() == "address1_city")
                {
                   
StringProperty property = (StringProperty)entity.Properties[i];
                    city = property.Value;
                }
            }
           
string result = "<table border=1><tr>";
            result +=
"<td>Ad</td>";
            result +=
"<td>Soyad</td>";
            result +=
"<td>Şehir</td>";
            result +=
"</tr>";
            result +=
"<tr>";
            result +=
"<td>" + firstname + "</td>";
           
result += "<td>" + lastname + "</td>";
            result +=
"<td>" + city + "</td>";
            result +=
"</tr></table>";
            lblMessage.Text =
"eşleşen kayıtlar bulundu";
            lblMessage.Text += result;
           
return true;
        }
       
return false;
    }
   
catch (Exception ex)
    {
        HandleException(ex);
       
return false;
    }
}

Daha önceden sitemize kayıt olmuş test1 kişisinin sitemize tekrar kayıt olmaya çalıştığını düşünelim uygulama eşleşen bir kayıt bulacağından görüntü şöyle olacak.




Bu makaleye de burada noktayı koyalım. Unutmayın sırada veri yazma ile ilgili bir makale var.

Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net 

Dynamics CRM , , , , , , , , , , , , ,

Microsoft Dynamics CRM 3.0 ‘dan Veri Sorgulama Yöntemleri -3 (FetchXML Kullanarak Veritabanına Erişim)

27. Ocak 2008

Microsoft Dynamics CRM 3.0 ‘dan Veri Sorgulama Yöntemleri -3 (FetchXML Kullanarak Veritabanına Erişim)

Önceki iki makalemde Microsoft CRM Web Servislerini ve Sql kullanarak veri sorgulama yöntemlerini örnekler vererek açıklamıştım. Son yöntemimiz ise FetcXML kullanarak CRM veri katmanına erişmek. Bu yöntem bir ad-hoc query yaratır ve bu query Microsoft CRM sistemi üzerindeki entityler üzerinde servisler vasıtasıyla icra edilir. Bu yöntemi QueryExpression (yani 1. makalede ele aldığım konu)'den farklı kılan taraf ise Fetch yönteminin bize Microsoft CRM BusinessEntity sinifindan bir XML döndürmesidir. 

FetchXML'in ayrı bir sorgulama dili olduğu ve kendi yazım kuralları olduğu unutulmamalıdır.

Bu yöntemi kullanarak veri okuyabilme işlemi sırasında sorguyu çağıran kişinin sistem erişim hakları (access rights) üzerinde Read privilege yetkisi olması gerekmektedir.

Biçim

			[Visual Basic]Public Function Fetch(  ByVal fetchXml As String) As String
			
			[C#]public string Fetch(  string  fetchXml);
			
			[JScript]public function Fetch(  fetchXml : String) : String;
			
Parametreler fetchXml : İcra edilecek Fetch query.
Dönen Değer String türünde içerisinde sorgu sonucunu bulunduran XML döner.
Sorgu İfadeleri
Koşul
Koşul İfadesi Değer
equals x eq x
does not equal x ne x
is greater than x gt x
is greater than or equal to x ge x
is less than x lt x
is less than or equal to x le x
begins with x like x%
does not begin with x not-like x%
ends with x like %x
does not end with x not-like %x
contains x like %x%
does not contain x not-like %x%
exists not-null  
does not exist null  
anytime not-null  
yesterday yesterday  
today today  
tomorrow tomorrow  
in next 7 days next-seven-days  
in last 7 days last-seven-days  
next week next-week  
last week last-week  
this week this-week  
this month this-month  
last month last-month  
next month next-month  
this year this-year  
next year next-year  
last year last-year  
on x on x
on or after x on-or-after x
on or before x on-or-before x
in between between  
not between not-between  
in in  
not in not-in  
equals user id eq-userid  
does not equal user id ne-userid  
equals business id eq-businessid  
does not equal business id ne-businessid  

Örnek Uygulama :
Yukarıdaki tabloda sorgu ifadeleri kısmında "Koşul İfadesi" kısmında yazan değerler bizim normal sql cümlesinde kullandığımız ifadelere benzemektedir. Tek fark "=","<",">" gibi ifadelerin yerlerine "eq","gt","lt" gibi text bazlı ifadelerin gelmiş olmasıdır. Aşağıdaki örnek kodda ben sql'den bildiğimiz "like" operatörünü kullanacağım.
Herzaman olduğu gibi şimdi de kod üzerinde açıklama yönetimi tercih ediyorum ki kodu uygulamalarınıza kopyalayıp yapıştırdığınızda açıklamalar da beraberinde kodun içinde olsun diye. Unutulmamalıdır ki buradaki uygulamayı çalıştırabilmeniz için Veri Sorgulama Yöntemleri-1 isimli makalemde yer alan CRM Web Servisinin eklenmesi adımının yapılmış olması gerekmektedir.

private
void btnQueryWithFetchXML_Click(object sender, EventArgs e)
{
   
try
    {
       
// CRM Servis'ini cagiriyoruz
       
CrmService service = new CrmService();
       
// servise network'te kim oldugumuzu soyluyoruz. (Eger CRM Server'i ile ayni domainde degilseniz
        // bunu yapmak zorundasiniz yoksa "The request failed with HTTP status 401: Unauthorized." hatasini alirsiniz)
        System.Net.NetworkCredential MyCredential = new System.Net.NetworkCredential();
        MyCredential.UserName = ""; // Domain Kullanici Adi
        MyCredential.Password = ""; //Domain Kullanicisinin Sifresi
        MyCredential.Domain = ""; //Domain Adi
        service.Credentials = MyCredential;
       
// Eger crm server ile ayni domainde iseniz ve sizin crm'de bir rolunuz varsa asagida parantezler icerisinde
        // belirttigim komutu yukaridaki 5 satir yerine kullanabilirsiniz
        // ( service.Credentials = System.Net.CredentialCache.DefaultCredentials; )
       
       
// Geri donecek butun Contact'lardan Contactid ve FullName degerlerini istiyoruz
        // Sehir ismi "Istanbul" olanlar cagiriyoruz.
       
string fetch = "<fetch mapping='logical'>"+
                                       
"<entity name='contact'>"+
                                           
"<attribute name='contactid'/>"+
                                           
"<attribute name='fullname'/>"+
                                               
"<filter type='and'>"+
                                                   
"<condition attribute='address1_city' operator='like' value='İstanbul'/>"+
                                               
"</filter>"+
                                       
"</entity>"+
                               
"</fetch>";
       
// Service'e gonderiyoruz
       
string result = service.Fetch(fetch);
       
MessageBox.Show(result);
        // Gelen result'u XML objeleri ile parse edebiliriz.
    }
   
// Soap yani Web Servisi hatalarini yakalamak icin ilgili Exception sinifimiz ekliyoruz.
   
catch (System.Web.Services.Protocols.SoapException ex)
    {
       
MessageBox.Show(ex.Message + " " + ex.Detail.InnerText);
    }
   
// Soap disindaki Standart hatalari yakalamak icin Exception'i da kodumuza ekliyoruz.
   
catch (Exception ex)
    {
       
MessageBox.Show(ex.Message);
    }
}

Microsoft CRM 3.0'dan veri sorgulama yöntemleri isimli makalemizin sonuna ulaştık. Umarım bu konuları detaylı açıklayabilmişimdir. Bana her türlü sorunda mail adresimden ulaşabilirsiniz. Yeni bir makalede görüşmek üzere.

Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net

Dynamics CRM , , , , , , , , , , ,

Microsoft Dynamics CRM 3.0 ‘dan Veri Sorgulama Yöntemleri -2(Sql Kullanarak Veritabanına Erişim)

27. Ocak 2008

Microsoft Dynamics CRM 3.0 ‘dan Veri Sorgulama Yöntemleri -2(Sql Kullanarak Veritabanına Erişim)

Bir önceki makalemde Microsoft CRM Web Servislerini kullanarak veri sorgulama yöntemine bir örnek vermiştim. Şimdi ise Microsoft CRM’in veritabanına bağlanarak veri sorgulayacağız. Tabii bu sorgulama işlemi biraz programlama bilen bir kişinin yapabileceği kadar basit ve standart bir işlem. Burada size bir sql cümlesiyle nasıl sorgulama yapılırın ötesinde CRM’in veritabanı yapısı hakkında bilgi vermenin daha faydalı olacağını düşünüyorum.

Microsoft CRM veritabanında bilmeniz gerekenler;

  1. Bizim üzerinde alan açmamıza izin verdiği bütün entitylerin(CRM tablo nesnesi) çift tablodan oluştuğudur.
  2. CRM standart kurulumunda bizim onun üzerine açtığımız bütün alanların ve tabloların başına “new_” ibaresini koyar.
  3.  Veri sorgulamakta direkt tablolardan veri sorgulamak Microsoft tarafından yasaktır.
  4.  Bu yüzden Microsoft programlarımızda ve raporlarımızda “FilteredView” ismi verilen güvenlik altyapısını içerisinde bulunduran viewları kullanmamızı ister.
  5. Veritabanında relation’lar(ilişkiler) için Guid adı verilen unique(tekil) bir tanımlayıcı kullanılır.
  6. Her ne şartla olursa olsun veritabanına direkt veri yazmak Microsoft tarafından unsupported (sisteminize zarar geldiğinde Microsoft tarafından destek alamayacağınız durum) unsur olarak değerlendirilir. Veri yazmak için web servislerini kullanmak gerekmektedir

Burada sanıyorum açıklanmaya en ihtiyaç duyulan madde 1. Madde. Account(Firma) kartını ele alarak açıklayayım; CRM’in Microsoft tarafından açılmış “name”,”accountnumber” gibi alanları “accountbase” tablosu üzerinde yer alırken, bizim vergi_numarası diye bir alanı açtığımızı varsayalım. Bu alan “new_vergi_numarasi” şeklinde “AccountExtensionBase” tablosu içinde açılacaktır. Bu iki tablo birbirine “AccountId” isimli alandaki Guid ile bağlanacaktır. Bu örnekteki yapı bizim alan açmamıza izin verilen tablolarda buna benzer şekilde olacaktır.
Eğer filteredview kullanacaksanız bu yapının farkında bile olmayacaksınız. Çünkü “filteredview”lar bu ilgili tabloları birbirlerine join yaparak(yani birleştirerek) getirmektedir. “Filteredview”’lar bize, güvenlik,silinmiş ve pasife çekilmiş kayıtları göstermeme gibi bizim uğraşarak yapmamız gereken birçok şeyi içerisinde yapmış bir veri sorgulama ortamı sunmaktadırlar.
Bir filteredview'in yapisini incelerseniz en az 50 tablo ile joinli oldugunu görebilirsiniz; Aşağıdaki resimde FilteredAccount isimli view'in yapisinin bir kısmını bulabilirsiniz (Daha resme sığmayan en az 30 tablo var resmin altında)



Ayrica Özelleştirilebilir tabloların Extension isimli ek tablolarını veritabanında görebilirsiniz.



Benim oluşturduğum test uygulamasının “Veri Çek (Using a Sql Data Access)” düğmesinin altında yer alan kod; (Yine daha kolay olması için kod makale bundan sonra kod üzerindeki açıklamalarla devam edecek)

private
void btnQueryOnSql_Click(object sender, EventArgs e)
{
   
//sql server'a baglanmak icin gerekli olan baglanti cumlesini olusturuyoruz.
   
string ConnectionString = "data source=**sql_server**;database=**veritabani_adi**;user=**kullanici_adi**;password=**sifre**;";
   
//Baglanti cumlesini baglanti nesnemize parametre olarak vererek baglanti nesnemizi olusturuyoruz
   
SqlConnection myConnection = new SqlConnection(ConnectionString);
    try
   
{
       
//sql server baglantisini aciyoruz.
        myConnection.Open();
       
//veri cekmekte kullanacagimiz sql cumlesini olusturuyoruz.
       
string SQLstring = "select fullname, contactid from filteredcontact where address1_city like stanbul";
       
//sql cumlesini ve baglantimizi vererek bir veri cekme arabirimi olusturuyoruz.
       
SqlDataAdapter myDataAdapter = new SqlDataAdapter(SQLstring , myConnection);
       
//Verileri icerisinde barindiracak olan nesnemizi olusturuyoruz.
       
DataSet myDataSet = new DataSet();
       
//Verileri dolduruyoruz
        myDataAdapter.Fill(myDataSet);
       
if (myDataSet != null)
        {
               
if (myDataSet.Tables[0].Rows.Count > 0)
                {
                   
//Verileri gostermesi icin grdi'e veriyoruz.
                    GridView.DataSource = myDataSet.Tables[0];
                }
       
        else
       
        {
                   
throw new Exception("DataSet nesnesi kayt iermiyor.");
                }
        }
       
else
            throw
new Exception("DataSet nesnesi null geldi");
    }
   
catch (Exception ex)
    {
       
MessageBox.Show(ex.Message);
    }
   
finally
    {
       
//Baglanti acik ise kapatiyoruz.
       
if (ConnectionState.Open == myConnection.State)
        myConnection.Close();
    }
}

Bir makalemizin daha sonuna geldik. Unutmayın veri sorgulama yöntemleri ile ilgili 1 makale daha var sırada.

Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net

Dynamics CRM , , , , , , , , , , ,

Microsoft Dynamics CRM 3.0 ‘dan Veri Sorgulama Yöntemleri -1 (Web Servisleri)

27. Ocak 2008

Microsoft Dynamics CRM 3.0 ‘dan Veri Sorgulama Yöntemleri -1 (Web Servisleri)

Microsoft CRM verilerini okumak isimli bir yazı dizisi oluşturmaya karar verdim. Bunun nedeni ise CRM ile uğraşan pek çok insanla tanışmam ve hepsinin farklı bir yol izlediğini görmem. Hepsi bir,iki yol biliyor ama çoğu eksik veya yanlış bilgilerle bu işi yapıyorlar. Bütün yöntemleri biraraya getirip anlatmak en iyisi olacak diye düşündüm.

Microsoft CRM üzerinde veri sorgulaması yapmanın üç yolu bulunmakta ve ben bu üç yolu, bu yazı dizisinde örnekleriyle anlatacağım. Bu üç yol sırasıyla, Web Servislerini kullanmak, Sql kullanarak veritabanına erişim ve FetchXML kullanmak. Yazımızın birinci bölümü web servisleri ile başlıyor;

Microsoft CRM, bizlere üzerinde uygulama geliştirmek için çok iyi bir platform mimarisi sunuyor. Bu mimarinin neredeyse temel yapıtaşı konumunda olan WebServis’leri ise bize özellikle veri yazarken büyük kolaylıklar sağlasa da veri okurken bazen karışık olabiliyor. Web Servisleri class(sınıf) mimarisinde olduğundan nesne paylaşımına dayalı bir altyapı sunuyor. Bu doğru kullanıldığında, bize, program yazarken uzun uzun attribute ve property hazırlamak derdinden kurtarıyor.

Microsoft CRM’in 2 adet temel Web Servisi bulunmakta;

  1. CRM Service : istediğiniz entity üzerinde Create(Oluşturma),Update(Güncelleme) , Delete(Silme) gibi işlemleri yapmanızı sağlıyor. Adresi;
    http://<yourservername(:port)>/mscrmservices/2006/crmservice.asmx
  2. Metadata Service : CRM’in entity ve picklist mimarisi gibi metadata veritabanında bulunan veriler üzerinde yine Create(Oluşturma),Update(Güncelleme) ,Delete(Silme) gibi işlemleri yapmanızı sağlıyor. Metadata verisi içerisinde bir picklist(yani combobox-dropdownbox)’in içeriği, bir alanın türü gibi sistem üzerinde kullandığımız nesnelere yönelik bilgileri tutmaktadır. Adresi;
    http://<yourservername(:port)>/mscrmservices/2006/metadataservice.asmx

Web Servisini Projemize Eklemek :



Visual Studio’da açtığımız uygulamamızın adı üzerinde sağ tuşa tıklayarak getirdiğimiz menüde aşağıdaki gibi “Add Web Reference”’a tıklıyoruz.

Açılan pencereye eklemek istediğimiz servisin url’ini yazıyoruz ve “go” düğmesine tıklıyoruz.





Servis credential yani kimlik doğrulamak için bizden kullanıcı adı ve şifre isteyecek. Bunu geçtikten sonra “Web reference name”’e servise verecegimiz ismi yazıyoruz. Burada ben “MyService” ismini veriyorum. “Add Reference” düğmesine tıklıyoruz.Artık servisimizi projemize eklemiş durumdayız.
XML Web Servisleri hakkinda daha fazla bilgi almak ve kendi web servislerinizi yazmak istiyorsaniz aşağıdaki linklerden gerekli bilgiye ulaşabilirsiniz;

http://www.yazgelistir.com/Makaleler/makaleler.aspx?KatId=1000000009&Kat=XML%20Web%20Servisleri

http://www.codeproject.com/cs/webservices/myservice.asp

Kod Yazmaya Başlamak:

Servisimizi ekledikten sonra kod yazma işlemine geçebiliriz. Örnek kod bize CRM Servislerini kullanarak “ select fullname, contactid from filteredcontact where address1_city like ‘İstanbul’ ’” sorgusunu nasıl çekebileceğimizi gösterecek. Uygulamamızın ekran görüntüsü aşağıdaki gibi olacak ve veri çektikten sonra(Veri Çek (Query Expression) düğmesine bastıktan sonra) bize mesaj kutusu içinde istediğimiz veriyi gösterecek

(Aşağıdaki örnek kodu kendi projeniz üzerine yapıştıbileceğinizi düşündüğümden makalemin bundan sonraki kısmına kod üzerindeki not alanlarında devam ediyorum.)
Düğmenin arkasında yazan kodlar ve bunların açıklamalaı ise aşağıdaki gibidir; (CRM nesnelerine kolayca erişmek için en tepeye “ using TestApplication.MyService; ” kodunu eklemeyi unutmuyoruz tabii ki) (TestApplication burada benim uygulamamın adı siz kendi uygulamanızın adını yazmalısınız bunun yerine)


private
void btnRetrieveData_Click(object sender, EventArgs e)
{
   
try
    {
       
// CRM Servis'ini cagiriyoruz
       
CrmService service = new CrmService();

       
// servise network'te kim oldugumuzu soyluyoruz. (Eger CRM Server'i ile ayni domainde degilseniz
        // bunu yapmak zorundasiniz yoksa "The request failed with HTTP status 401: Unauthorized." hatasini alirsiniz)
        System.Net.NetworkCredential MyCredential = new System.Net.NetworkCredential();
        MyCredential.UserName =
""; // Domain Kullanici Adi
        MyCredential.Password =
""; //Domain Kullanicisinin Sifresi
        MyCredential.Domain =
""; //Domain Adi
        service.Credentials = MyCredential;
       
// Eger crm server ile ayni domainde iseniz ve sizin crm'de bir rolunuz varsa asagida parantezler icerisinde
        // belirttigim komutu yukaridaki 5 satir yerine kullanabilirsiniz
        // ( service.Credentials = System.Net.CredentialCache.DefaultCredentials; )
        // istedigimiz sutunlari getirmemizi saglayacak olan ColumnSet nesnemizi olusturuyoruz.

        ColumnSet cols = new ColumnSet();
       
// ColumnSet nesnemize geri dondurmek istedigimiz sutunlarin adini veriyoruz.

        cols.Attributes =
new string[] { "fullname", "contactid" };
       
// ConditionExpression nesnemizi olusturuyoruz.

       
ConditionExpression condition = new ConditionExpression();
       
// Bize donecek olan contact'lar icerisinde adresinin sehri stanbul olanlari filtreliyoruz.

        condition.AttributeName =
"address1_city";
        condition.Operator =
ConditionOperator.Like;
        condition.Values =
new string[] { "stanbul" };

       
// FilterExpression nesnemizi olusturuyoruz.
       
FilterExpression filter = new FilterExpression();
       

        // Yukarida olusturdugumuz kosul filtresini FilterExpression'a veriyoruz.
        filter.FilterOperator = LogicalOperator.And;
        filter.Conditions =
new ConditionExpression[] { condition };

       
// QueryExpression nesnemizi olusturuyoruz.
       
QueryExpression query = new QueryExpression();

       
// Yukarida olusturdugumuz filtremizi ve donmesini istedigimiz sutunlari QueryExpression'a veriyoruz.
        query.EntityName = EntityName.contact.ToString();
        query.ColumnSet = cols;
        query.Criteria = filter;

       
// Bu kosula uyan contact'lari sistemde sorgulatiyoruz.
       
BusinessEntityCollection contacts = service.RetrieveMultiple(query);
       
if (contacts != null)
           
if (contacts.BusinessEntities.Length > 0)
            {
           
    //BusinessEntityCollection array'indan sorgulama sonucunda donen ilk degeri aliyoruz.
                //Ve bu ilk degeri contact sinifina ceviriyoruz.
               
contact myContact = (contact)contacts.BusinessEntities[0];
               
if (myContact != null)
                {
                   
//artik elimizde olan contact sinifi ile yukarida bize donmesini istedigimiz sutunlarin
                    //iceriklerini alabiliriz.
                   
MessageBox.Show("ad-soyad:" + myContact.fullname.ToString() + " id:" + myContact.contactid.Value.ToString());
                 }
            }
    }
    // Soap yani Web Servisi hatalarini yakalamak icin ilgili Exception sinifimiz ekliyoruz.
   
catch (System.Web.Services.Protocols.SoapException ex)
    {
       
MessageBox.Show(ex.Message + " " + ex.Detail.InnerText);
    }
   
// Soap disindaki Standart hatalari yakalamak icin Exception'i da kodumuza ekliyoruz.
   
catch (Exception ex)
    {
       
MessageBox.Show(ex.Message);
    }
}


Programımızı çalıştırdığımızda bize istediğimiz bilgiyi sorgulayıp getirecektir. Bir makalemizin daha sonuna geldik. Unutmayın veri sorgulama yöntemleri ile ilgili 2 makale daha var sırada.

Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net

  

Dynamics CRM , , , , , , , , ,