#Sharp.Net - Suat Tuncer

14/11/2008 - Asp.Net MVC Framework

Kategori: CSharp

İsim şahane acayip çekici işin içine bir MVC patterni eklenince dayanamıyor insan ağzı sulanıyor fakat madalyonun öteki yüzü böyle değil.

Yeni projemizi MVC paternini uygulayarak geliştirmeye karar verdik ve nede olsa "yabancı" değildir diye microsoft cephesinden Asp.Net MVC Framework'ü incelemeye başladık mamahif indirdiğim sample ile yüklediğim sürüm arasındaki kodlarda bile farklıklar var. Controler methodlarında ciddi değişiklikler yapılırken bir obsolute veya beta attribute bile kullanmadan iterasyonu yapılmış. beta olarak lanse edilsede bu ürün, bence gelişimi için uzunca bir zamana daha ihtiyacımız var.

Ayrıca ne olacak bu web'in Microsoft'tan çektiği. Web uygulamları geliştirme konusnda web formlar ile çok farklı bir yaklaşım getirmişti ki  çok değil geçen senelerde browser application adıyla WPF 'dan bahsetmeye başladı. Şimdide tekrar bir değişiklik ile Asp.Net MVC. tamam güzel hiç birini iptal etmiyor hep üzerine katıyor ama her biri biraz eksik kalıyor. Artık birini mükemmelleştirmeli diye düşünüyor ve buradan bizzat kendilerine sesleniyorum :-).

Bir web teknolojisi istiyorum. 

OOP olsun.
Hafif olsun
Modellemesi kolay olsun
Zengin olsun.

Yorum (yok) :: Yorum yaz! :: Bağlantı

31/10/2008 - NHibernate ve Performans

Kategori: CSharp

Çok uzun olmamakla beraber bir süredir proje geliştiriken NHibernate kullanıyorum. Aslında oldukça pratik bir tool. Özellikle nesnelerin rahatlığını size sunduğu için odağınızı neredeyse tamamen uygulama katmanına kaydırıyor, buda daha kaliteli, okunabilir ve yüksek oranda object oriented bir kodun orataya çıkmasını sağlıyor.

Fakat yaşadığım bir kaç sıkıntıyı paylaşmak isterim. Create, Update ve Delete işlemlerinde oldukça hızlı ve sorunsuz çalışmasına rağmen sorgulama özellikle de raporlamada çok ciddi performans sıkıntıları var, tabi burada problem birazda benim raporlama kaynağı olarakta object collectionlar kullanmak istememden kaynaklanıyor.

Tavsiyem sorgulamada HQL veya SQL kullanılmasından yanadır özellikle complex raporlama tarzı sorgularda kesinlikle IQuery interfacesi kullanılmalı ICriteria değil. Benim tercihim HQL hernekadar SQL tarzı sıkıcı sorgular yazmak zorunda kalsamda nesne sorguladığım için daha keyifli ve kullanışlı. Gönül isterdiki LINQ ile NHibnernate kardeş kardeş çalışsın mamhif henüz mümkün değil.

Yorum (4) :: Yorum yaz! :: Bağlantı

3/8/2007 - Dış Dünyayla Proxy Server Üzerinden Konuşmak

Kategori: CSharp

 

Büyük şirketlerde ve kurumsal yapılar içersinde ISA server olmazsa olmaz yapılardan biridir. Her türlü network trafiğini kontrol altında tutmak için en ideal yoldur. Amaç tüm network trafiğini izlemek ve denetim elde tutumak olunca işin içne kaçınılmaz olan güvenlik girmektedir.

 

Bir çoğumuzun bildiği gibi ISA Client nesnesi üzerinden dışarıyla konuşmak için üyesi olduğumuz networkte geçerli bir Kullancı Adı ve şifreye sahip olmak şarttır suat.tuncer@sirket.com gibi.

 

Böyle bir networkte dışarıya çıkmanın tek yolu proxy serverı kullanmaktır. Bunu yapmak için Internet Explorer’ın connection kısmında proxy server adresini girmek yeterlidir.

 

IE 7.0’da ISA Client’ın Yapılandırdığı Proxy Ayarları

 

Fakat yazdığımız uygulamalarda bu yeterli değil. Güvenliğin arttılıdığı ve kısıtlamaların arttığı WAN’larda özellikle dışarıya çıkmak isteyen uygulamalar söz konusuysa bu işi bizim yapmamız gerekir.

 

Bu yazıda kısaca bu problemin nasıl aşılacağını anlatacağım. Öncelikle basitce webden bir dosya almaya çalışalım.

 

using System;

using System.Collections.Generic;

using System.Text;

 

using System.Net; //webclient nesnesi için

 

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            WebClient client = new WebClient();

            client.DownloadFile("http://img.blogcu.com/uploads/suattuncer_20051018.jpg", "c:\dosya.jpg");

        }

    }

}

 

Yukarıdaki dosya alınmaya çalışıldığında aşağıdaki gibi bir hatayla karşılaşmaktayım, Bu arada hemen belirteyim bu hatayı, ancak ISA Server bulunan ve Proxy Authentication isteyen bir NetWorkde görebilirsiniz

 

 

Bu problemi aşmanın yolu Domain hesabımızı kullanmak olacaktır. WebClient nesnesi incelendiğinde bu gibi sorunları aşması için Credential gibi bir özelliğe sahip olduğunu göreceksiniz, .Net’de,  System.Net altında yeralan bir çok sınıfın Credential özelliği bulunmaktadır. Bir ağ kimliği oluşturarak Proxy üzerinden yada herhangi bir network üzerinden dışarıya çıkmak için kullanılmaktadır.

 

 NetworkCredential Nedir ?

 

Network üzerinde geçerli olan bir kimlik gibi düşünülebilir. Kısıtlanmış ve Authentication’a bağlı noktalarda uyugulamayı kullanan kişinin kendini doğrulamak için çıkartıp göstereceği kimliktir.  Tıpkı yukarıdaki hata mesajında bahsedildiği gibi : “Proxy Authentication Required”

 

Yukarıdaki kodu aşağıdaki gibi revize edip tekrar çalıştırdığımızda sorunsuz çalıştığını göreceksiniz.

 

using System;

using System.Collections.Generic;

using System.Text;

 

using System.Net;

 

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            WebClient client = new WebClient();

 

            //networkde geçerli bir limlik tanımlaması yapılıyor

            NetworkCredential kimlik = new NetworkCredential();

            kimlik.Domain = "sirket.com";

            kimlik.UserName = "suat.tuncer";

            kimlik.Password = "password";

 

            //Proxy server tanımlanıyor

            WebProxy proxyServer = new WebProxy("10.1.0.100", 8080);

 

            //proxy sunucu üzerinden doğrulanacak kimlik

            proxyServer.Credentials = kimlik;

 

            //WebClient nesnesinin dışarıya hangi sunucu üzerinden çıkacağı belirtiliyor

            client.Proxy = proxyServer;

 

            // artık güvenliğe takılmadan dosya indirilebilir

            client.DownloadFile("http://img.blogcu.com/uploads/suattuncer_20051018.jpg", "c:\dosya.jpg");

        }

    }

}

 

NetworkCredential        : Network üzerinde doğrulanacak bir kimlik tanımlamak için kullnılır

WebProxy                          : Konu başında anlattığım Proxy Server’ın ta kendisi kodumuzdaki, Network trafiğinin hangi sunucu üzerinden gerçekleşeceğini belirtir.

 

Belki her durumda değil ama sıkı güvenlik kurallarının olduğu NetWorklerde ihtiyaç duyduğum bir yapıydı.

Soru ve Önerileriniz için

suattuncer@hotmail.com   .::.   http://suattuncer.bloguc.com

 

 

Yorum (5) :: Yorum yaz! :: Bağlantı

21/1/2007 - Bir Saldırının Anatomisi ve AppDomain Sınıfı

Kategori: CSharp

Bir Saldırının Anatomisi ve Application Domain Sınıfı-1

 

Bu yazı gerçek bir hikâyeden alınmıştır, Kişilerin takma adları kullanılmıştır.

Dromedary o gece sabaha karşı uymuştu ve şimdi uyanmak oldukça zor geliyordu, oda tıpkı diğer yazılımcılar gibi geceleri çalışmayı seven biriydi. Sabah güçlüklede olsa yatağından doğruldu ve hızlıca hazırlanıp evden çıktı. Şirkete geldiğinde mesai henüz  başlamamıştı. Masasına geçip bilgisayarını açtı ve sistemi kontrol etti, herşey yolundaydı . Dromedary CSoft’da yazılım uzmanı olarak çalışıyordu.Bir ekip olarak, Visual Studio 2005 üzerinde C# ile geliştirdikleri tedarik zinciri projesi test aşamasına gelmişti ve bazı kullanıcılılar tarafından gerçek verilerle test edilmekteydi.  Bu yüzden, düzenli olarak her sabah uygulamanın kullandığı DataBase Server’i kontrol ediyordu.

Saat öğlene yaklaştığında test kullanıcılarından biri server’a login olurken hatayla karşılaştığını ve ani bir yavaşlama yaşadığını raporetti. Dromedary hemen server hareketlerini tekrar gözden geçirdi ve logları inceledi. Test kullanıcısın hesabıyla oturum açılmış görünüyordu hesabı düşürüp tekrar bağlanmasını sağladı. Fakat dikkatini çeken bir durum daha vardı. Gece geç saatlerde bir hareketlilik yaşanmıştı ve istemci olarakta geliştirdkleri program görünüyordu.  Programın kaynak kodlarını incelemeye başladı fakat herşey normal görünüyordu.  Önemsiz olabileceğini düşündü ve bunu not edip rutin işlerine geri döndü.

 Akşam çıkış saatine doğru öğlen yaşanan olayla ilgili kafasında tekrar soru işaretleri oluştu ve kalıp DataBase Server’ı izlemeye karar verdi. Saat oldukça geç olmuştu ama olağan dışı bir durum yaşanmamıştı. Kalkıp bir kahve aldı ve tekrar masısına oturup DBTracer programını açtı, tam bu sırada bir hareketlilik yaşandı. Geliştirdikleri Uygulama üzerinden Server’a  bir bağlantı yapılmıştı veriler inceleniyordu, kayıtlara bakılıyordu. İstemcilerin bağlantı bilgilerinin tutulduğu tabloyu açıp IP adresi ve kullanıcı adı bilgilerine baktığında test kullanıcılarından biri olduğunu farketti. IP adresini araştırdığında adresin Bağcılar çıkışlı olduğunu gördü. Oysa bu kullanıcı hesabı Kadıköy’dek bir şirkete aitti. Kesinlikle bu başka biriydi ve Geliştirilen uygulame ile birlikte kullanıcı bilgilerinide ele geçirmişti.

Server’da tutulan bilgiler, test amaçlı olduğu için çok önemli değildi fakat gerçek verilerle örtüşen kayıtlarda yer almaktaydı Bağlanan kişiyi farkettiğini belli etmemek için server’ı farklı bir adrese yönlendirdi. Aynı kullanıcı yaklaşık bir hafta önce uygulamanın hatalar ürettiğni rapor etmişti. Bu sorun, direk Dromedary’a rapor edilmemişti ve başka bir arkadaşı uygulamayı yeniden kurup çalışır hale getirmişti. Hemen geçen hafta kullanıcı pc’sine uygulamayı tekrar kuran arkadaşı Barış’ı aradı. Uygulama dizininde bir anormallikle karşılaşıp karşılaşmadığını sordu. Barış, sadece uygulamanın kullandığı CheckPoint.dll dosyasının zarar gördüğünü, onarmak için tekrar kurduğunu söyledi.

Bu bilgiden sonra Dromedary incelemelerini tamamen bu dll üzerine yoğunlaştırdı. Bu dll dosyası uygulama her çalıştırıldığında ilk çağrılan, içerisinde bir çok Class yeralan bir dll’di ve tabiki kendileri yazmıştı. Yavaş yavaş işi anlamaya başlıyordu, ve tahmin ettiği gibi DLL dosyası üzerinden kendi uygulamaları kullanılarak sisteme sızılmıştı. Dromedary sonradan öğrenecekti,  aslında bu işi yapan kişi merXas’tan başkası değildi

merXas sadece uygulamanın kullandığı CheckPoint.dll dosyasını kendi istediği işleri yapıcak bir hale getirmiş ve uygulamayının referanslarında yer alan orjinal dll ile değiştirmişti. Bu sayede uygulama , kendisine ait olan bir dll’e, bir proxy dll üzerinde ulaşıyordu. Bu tüm akışın izlenmesini ve istenilen verilerin elde edilmesini sağlamıştı tıpkı kullanıcı adı ve şifrelerin alındığı gibi,

 

Şekil-1 : Uygulamanın Orjinal Hali

 

Şekil-1 : Uygulamanın proxy dll ile bozulmuş hali

Peki böyle bir açık kapatılamazmıydı, evek kesinlikle kapatılabilirdi. Zaten merXas ’da,  uygulamayı incelerken uygulamanın AppDomain sınıfını kullanmadığını, yani program içerisinde kullanılan Assemblylerin izole edilmediğini ve güvenlik seviyelerinin ayarlanmadığını farkettikten sonra,  bu yöntemi kullanmaya karar vermişti. Peki nedir bu AppDomain sınıfı ve güvenlik seviyeleri;

AppDomain sınıfı .Net uygulamalarında, uygulamaların diğer .Net uygulamlarından ve kendi içerisinde kullandığı Assemblyleri bir birinden izol etmek için kullanılan bir sınıfdır. Bu sınıfda Application Domainler yer alır. Application Domainler Assemblyler’i yalıtmak için kullanılan sınırlayıcılar gibi düşünülebilir. Aşağıdaki şekilde görüldüğü gibi uygulamanın ADMain isminde bir Application Domaini ve bunun içerisinde yer alan diğer Application Domainler ve her domainin içerisinde yer alan Assembly’leri bulunuyor.

 

ADMain

ADVeriTabaniKodlari

ADKullaniciKodlari

CheckPoint

DataObjects

UserSys

 

İşte böyle bir  yapı kurulmadan oluştulan Csoft projesinde merXas bu açığı sömürerek uygulamayı kendi istediği işleri yapıcak şekilde revize etmişti. Peki Dromedary bunu nasıl kullanmalıydı, yapıcağı işlem aslında oldukça basitti bir domain oluturup güvenlik seviyesi belirlemek, şöyleki;

Herhangi bir proje içerisinde kullanılacak her nesne, yeni olluşturulacak her nesne bir domain üzerinden instance edilmeli, bunu için her class MarshalByRefObject sınıfından türemiş olmalıdır.

Yani Dromedary CheckPoint Clasını şu şekilde yazmış olsaydı;

 

namespace CheckPoint

{

    public class CheckPoint : MarshalByRefObject

    {

 

        //CSoft projesindeki, uygulama ve db arasındak yapılanmayı sağlıyan

        //ve uygulamayı kullanıma hazır hale getiren bir methodu inceleyelim

        public void StartInterraction()

        {

            //burada çalıştılmak istenen kodlar

        }

 

    }

}

Class yukarıdaki gibi düzenlendikten sonra, şöyle çağırlmalıydı

//Class’ ın instance edileceği domain

AppDomain ad = AppDomain.CreateDomain("CheckPoint");

//instance edilen clasın ObjectHandle bilgisi tutulacak

ObjectHandle objHandle;

//nesne instance ediliyor ve instance edilen objenin handle adresi

objHandle = ad.CreateInstance("CheckPoint", "CheckPoint.CheckPoint");

//instance edilen nesnenin .StartInterraction() metodu çağrılıyor

((CheckPoint.CheckPoint)objHandle.Unwrap()).StartInterraction();

Buraya kadar yaptıklarımız , AppDomain sınıfını sadece yalıtım seviyesinde kullanmaktı. Burası önerilen bir yönetem değildir. Güvenlik seviyesiyle kullanılması daha sağlıklı olacaktır. Günvelik seviyesinde kullanmak içinde tasarım iyi yapılmalı.

Burada çok önemli iki ayrım söz konusu, güvenlik sınırlamaları assembly seviyesindemi olacak domain seviyesindemi !!, Tavsiyem domain seviyesnde olmasıdır. Böylece genel bir kontrol sağlanmış olur. Aynı zaman güvenlik seviyesi düşük yada bulunmayan bir Application Domain’den assembly lerin sızması  önlenmiş olur. Ununtmadan aynı zamanda bir Application Domain içerisinde hem domaine hemde assembly’e ayrı ayrı güvenlik seviyeleri uygulanabilir.

/* güvenlik seviyesi için gerekli bilgiler oluşturuluyor */

// Assembly'nin çalışacağı ortam

Zone bolge = new Zone(SecurityZone.Internet);

//ortam dışında bilgiler varsa bunlarda izinler dizisine aktarılabilir

object[] izinler = new object[1];

izinler[0] = bolge;

//güvenlik bilgileri Evidence nesnesne aktarılıyor

Evidence guvenlik = new Evidence(izinler, null);

//clasın instance edileceğii domain

AppDomain ad = AppDomain.CreateDomain("CheckPoint", guvenlik);

//instance edilen clasın ObjectHandle bilgisi tutulacak

ObjectHandle objHandle;

//nesne instance ediliyor ve instance edilen objenin handle adresi

objHandle = ad.CreateInstance("CheckPoint", "CheckPoint.CheckPoint");

//instance edilen nesnenin .StartInterraction() metodu çağrılıyor

((CheckPoint.CheckPoint)objHandle.Unwrap()).StartInterraction();

                Artık yeni oluşturduğumuz nesnemiz sadece İnternet ortamında çalışacak seviyede ayarlandı, bunun avantaji yerel sisteme hiç bir şekilde müdahele edememesidir. Böylece bilgisayardan kullanıcının yetkisi olmadan hiç bir veri okuyamaz hiç bir yere kayıt yapamaz daha güvenli bir ortam sağlanmış oldu.

                Bu uygulamları yapabilmek için projeye aşağıdaki NameSpacelerin dahil edilmesi gereklidir

using System.Runtime.Remoting;

using System.Security;

using System.Security.Policy;

CSoft böyle bir kaç güvenlik önemlemiyle bu sıkıntıdan kurtulabilirdi, peki bizler herşeyiyle güvenli tasarlanmış bir uygulama nasıl geliştirebilriiz ? Bununla ilgili detaylı örneği Applicatin Domain ve Günvelik konulu yazıda bulacaksınız

Devam edecek...

Yorum (3) :: Yorum yaz! :: Bağlantı

22/11/2006 - VB.Net - C#

Kategori: CSharp

        Bugüne kadar rastladığım en iyi hazırlanmış ve en açıklayacıyı VB.Net ile C# arasındaki farkları gösteren tablo, yavru kurtlara duyrulur :-) VB.NET and C# Comparison

Yorum (2) :: Yorum yaz! :: Bağlantı

15/11/2006 - X-Y Dağılım Grafikleri (X-Y Scatter Chart)

Kategori: CSharp

Merhabalar,

Uzun bir süre önce MsChart kontrolü ve grafik çizimi ile ilgili bir makalem www.yazilimuzmani.com adresinde yayinlanmıştı. Şimdi ise bir kaç gün önce aldığım bir mailde karşılaşılan bir sorundan yola çıkarak Microsoft Office Web Components ile XY Dağılım ( Scatter ) grafikleri oluşturmayı anlatacağım.

Öncelikle bu iş için sisteminizde office tools yüklü olmalı eğer yüklü değilse Microsoft Office Web Components adresinden indirebilirsiniz. Dil desteği mevcuttur. Türkçe seçilirse birlikte gelen yardım dosyasıda türkçe gelmekte ve programlama kütüphanesi hakkında kısıtlıda olsa bazı bilgiler yer almakta tercih size kalmış.

Eklentiyi indirip kurduktan sonra, şimdi yeni bir projeyle işe başlıyalım. File menüsünde New> Prject ve C# Windows Application ‘ı oluşturuyoruz. Toolbox üzerinde sağ tıklayıp Choose Items.. ‘ı tıklıyoruz.



Karşımıza gelen erkandan aşşağıdaki kontrolü seçip toolbox’a ekilyoruz.




Daha sonra Forma, bir button( button1)  ve bir ChartSpace (AxChartSpace1) kontrolü ekliyoruz. Sıra geldi kodlamaya ben örnek olarak mailime gelen verileri kullanıcam, tabi önce bunları SQL serverda bir tablo oluşturup orya attım, kullandığım örnek tablo şöyle ;




Burda veriler önem kazanıyor, veri kaynağı pek önemli değil çünkü verileri, dizilere aktarıp diziler yardımıyla serileri oluşturduk, yani veri kaynağı olarak SQL, OLDB, Text File bile kullanılabilir, bu arada ilk fırsatta doğrudan veri kaynağıyla iligili bir örnek hazırlıyacam, çünkü en çok sorun yaşanan noktalardan biride orası. Örneğimizde S1X ve S2X verileri ortak veriler, S1Y ve S2Y verileri ise değişken veriler, birde Kategori değerlerimiz var bunlar verileri sınıflandırma için yani dağılımı kategoriler üzerinde gerçekleştirmek için ihtiyaç duyacağımız veriler. Örnek vermek gerekirse;
Ocak - Aralık ayları (kategoriler) arasında, aynı yük yüksekliklerdeki (X değerleri)  farklı basınçlar (Y değerleri) diyebiliriz.

button1_click olayına şu kodları yazıyorum;

private void button1_Click(object sender, EventArgs e)
{
    //değerleri veri tabanında okuyorum
    //verilerin formatı tablodaki gibidir
    //uygun veriyle sizede yapabilirsiniz
    //veri problem olursa haber verin göndereyim :-)
    SqlConnection cn = new SqlConnection("Data Source=.;Initial " +
                    Catalog=Test;Integrated Security=SSPI;");
    SqlCommand cmd = new SqlCommand("select * from degerler", cn);
    DataTable dt = new DataTable();
    SqlDataAdapter da = new SqlDataAdapter(cmd);
    da.Fill(dt);
    //okunan değerler diziye aktarılacak
    //öncelikle diziler tanımlanıyor
    int length;
    length = dt.Rows.Count - 1;
    object[] categories = new object[length];
    object[] series1XValues = new object[length];
    object[] series1YValues = new object[length];
    object[] series2XValues = new object[length];
    object[] series2YValues = new object[length];
    //referances tipde bir datarow değişken ile
    //datatabledeki tüm satırları gezip diziye aktarıyorum
    DataRow r;
    for (int i = 0; i < dt.Rows.Count - 1; i++)
    {
        r = dt.Rows[i];
        categories[i] = r["CATID"];
        series1XValues[i] = r["S1X"];
        series1YValues[i] = r["S1Y"];
        series2XValues[i] = r["S2X"];
        series2YValues[i] = r["S2Y"];
    }
    /*şimdi garfiği çizdirmek için gereken kodlar*/

    //bunlar kodda kolaylık olsun diye tanımlıyorum
    //direkde kullanılabilir
    OWC10.ChChart MyChart;
    OWC10.ChSeries Series1;
    OWC10.ChSeries Series2;

    //grafik alanına yeni bir grafik nesnesi ekleniyor
    MyChart = axChartSpace1.Charts.Add(0);
    //grafik tipi X-Y dağılım (Scatter ) olarak ayarlıyorum
    MyChart.Type = OWC10.ChartChartTypeEnum.chChartTypeScatterSmoothLine;

    /* dizilere aktarılan verileri serilere aktarıyorum
     * dizilerin tanımladığım isimlerdenden anlaşılacağı gibi
     * her seride 1 X ve Y değeri olmak zorunda categori değeri ise
     * tüms eriler için ortak kullanılıyor
     * ve dağılımı gerçekleştirmek için mutlaka gerekli*/

 
    //grafik nesnesine yeni bir seri ekliyorum
    Series1 = MyChart.SeriesCollection.Add(0);
    //seriye değerlerini aktarıyorum SetData methodundaki
    //dimension parametresi verilerin türüü belirliyor burası dikkali kullanılmalı
    Series1.SetData(OWC10.ChartDimensionsEnum.chDimCategories, -1, categories);
    Series1.SetData(OWC10.ChartDimensionsEnum.chDimXValues, -1, series1XValues);
    Series1.SetData(OWC10.ChartDimensionsEnum.chDimYValues, -1, series1YValues);
 
    // ve şimdi 2. seride aynı şekilde oluşturuluyor
    //daha çoks eride eklenebilir bendeki veriler şimdilik bu kadar :-)
    Series2 = MyChart.SeriesCollection.Add(1);
    Series2.SetData(OWC10.ChartDimensionsEnum.chDimCategories, -1, categories);
    Series2.SetData(OWC10.ChartDimensionsEnum.chDimXValues, -1, series2XValues);
    Series2.SetData(OWC10.ChartDimensionsEnum.chDimYValues, -1, series2YValues);
    //ve perde 
}


Sonuç itibariyle garfiğimizin son hali budur, veriler ve fikir için Özer Kaymak'a teşekkürler

Yorum (4) :: Yorum yaz! :: Bağlantı

14/11/2006 - C# - IsNumeric

Kategori: CSharp
Merhaba,
VB'de çok sık kullanılan IsNumeric fonksiyonunu C#'a geçen bir çok kişi ah ahh canım Visual Basic'iğim diye yadetmektedir. İşin aslı C#'da IsNumeric fonksiyonu yerine IsNumber fonksiyonu mevcuttur fakat sadece char tipinde çalışmaktadır. Haliyle char tipinde çalıştığı için string (string aslında char dizisi olduğunda dolayı) tipindede çalıştırabiliriz, nasılmı şöyle ;

        public static bool IsNumeric(string value)
        {
            foreach (char c in value)
                if (!((Int16)c > 47 && (Int16)c < 58)) return false;
            return true;
        }


string alır bool döner, object almaya pekde gerek yok kanımca :-), ama ondalık sayılar içinde bi kontrol gerekiyor.

Yorum (1) :: Yorum yaz! :: Bağlantı

30/10/2006 - DataTable Üzerinde Distinct ve GroupBy

Kategori: CSharp
        Merhaba, T-SQL'de yer alan Distinct fonksiyonu ve Group By clause'unu birçok defa kullanmışızdır, ne iş yaptıklarıda malum yinede şurdan buradan bakılabilir,
        Dönelim konumuza sorun şuki DataTable'e çekilen veriler üzerinde bu fonksiyonları uygulamak hazır fonksiyonlarlar mümkündeğil ve .Net Framework ne yazıkki bu konuda hazır bir fonksiyon içermediği için iş başa düştü, kendi faonksiyonumu hazdım buraya ekliyorum, kullanabilirsiniz


        Şimdi bu fonksiyon ne iş yapar; Diyelimki veritabanından verilerimizi çekmişiz ama öyle bir select sorgusuyla değil, iç içe sorgular, fonksiyonlar, hesaplamalarla çekmişiz. Bu titiz çalışmanın sonucu elimizde sadece bir tablo var fekat biz bu tablo üzerinde bir daha çalışmak istiyoruz. Örneğin verileri bir daha gruplamak istiyoruz fakat bunu T-SQL ile yapamıyoruz çünkü yazdığımız sorgu buna izin vermiyor. Çok abartı bir örnek oldu değilmi, yok yok hiçte öyle olmadı,değil çünkü, aynı böyle bir durumla karşılaştım bugün ve oturdum böyle bir fonksiyon yazdım.

public class SharpSql
{
    public SharpSql(){}

    public DataTable Distinct(DataTable dataSource,
                                 string distinctColumn)
    {
        DataTable returnTable=new DataTable("distinctTable");
        /*
         * kaynak tablodaki sütunları
         * geri dönecek tabloya kopyalıyorum
         * böylece direkt satır eklenirken
         * sütunların birebir eşleşmesini sağlıyorum
         */
        foreach(DataColumn c in dataSource.Columns)
        {
            returnTable.Columns.Add(c.ColumnName,c.DataType);
        }
        bool hasRow=false;
        foreach(DataRow selectedRow in dataSource.Rows)
        {
            /*
             * kaynak tabloda herbir satırı seçip
             * sonuçların bulunduğu tabloda benzerinin
             * olup olmadığına bakıyorum
             */
            foreach(DataRow r in returnTable.Rows)
            {
                /*
                 * eşleşen sonuçlar bulunursa,
                 * satırın var olduğu anlamında
                 * hasRow=true yapıyorum
                 */
                if(r[distinctColumn].ToString() ==
                    selectedRow[distinctColumn].ToString())
                {
                    hasRow=true;
                    break;
                }
            }
            /*
             * Seçili satır bulunmamışsa hasRow değeri
             * varsayılan olarak false olacağı için,
             * satır ekleniyor
             */
            if(hasRow==false)
                returnTable.Rows.Add(selectedRow.ItemArray);
            hasRow=false;
        }
        return returnTable;
    }
    /*
     * her bir sütunun kendi toplamına ihtiyacım vardı
     * ve normal DataColumn'da böyle bir değer yoktu
     * bir class oluşturup inherit ettikten sonra
     * Toplam property'sini ekledim
     */
    public class GroupColumn:System.Data.DataColumn 
    {
        private double dblToplam;
        public GroupColumn(string columnName)
        { this.ColumnName=columnName; }

        public double Toplam
        {
            get{return dblToplam;}
            set{dblToplam=value;}
        } 
    }
    /*
     * ve yine tip dönüşümlerinde normal DataColumnCollection,
     * inherits edilmiş GroupColumn classında
     * tip dönüşüm hatası verdiğinden bunun yerine
     * kendi GroupColumnCollections'ımı yazdım 
     */
 
    public class GroupColumnCollection:CollectionBase 
    {
        public GroupColumnCollection(){}
        public void Add(GroupColumn obj)
        { this.InnerList.Add(obj);} 
    }

    public DataTable GroupBy(DataTable dataSource,
                     GroupColumnCollection columns,
                                 string groupByColumn)
    {
        /*
         * Gruplanırken, unique kolonlara göre
         * istenilen toplamlar alınıyor
         * Unique(benzersiz) sütunlar yazdığım
         * Distinct fonksiyonu ile eldeediliyor
         */
        DataTable tableDistinct;
        tableDistinct=this.Distinct(dataSource,groupByColumn);
        /*
         * dataview kullanılıyorki her bir 
         * groubBy kolonuna göre 
         * ayrı ayrı sonuçlar alınsın diye
         */
        DataView viewResult=new DataView();
        viewResult.Table=dataSource;
        DataTable returnTable=new DataTable("groupTable");
        DataRow returnRow;
        //Sütünlar ekleniyor
        foreach(GroupColumn c in columns)
        {
            returnTable.Columns.Add(c.ColumnName,c.DataType);
        }
        //Adet sütünü ekleniyor
        returnTable.Columns.Add("Adet");
        //Gruplamada kullanılan sütunu ekliyorum
        returnTable.Columns.Add(groupByColumn);
        //Toplamları hesaplayp ekliyorum
        foreach(DataRow r in tableDistinct.Rows)
        {
            viewResult.RowFilter =groupByColumn + " = '" 
                        + r[groupByColumn].ToString() + "'";
            //Yeni bir satır oluşturuyorum
            returnRow = returnTable.NewRow();
            /*
             * dataviewe rowfilter uygulandıktan sonra 
             * kalan satırlar geziliyor ve 
             * toplamları hesaplayıp
             * değerleri yeni satıra atıyorum
             */
            for(int  i=0;

                        i<=viewResult.Count;

                        i++)
            {
                foreach(GroupColumn c in columns)
                {
                    c.Toplam += Convert.ToDouble(viewResult[i][c.ColumnName]);
                    returnRow[c.ColumnName]=c.Toplam;
                }
            }
            //Grup adı ve adetini ekliyorum
            returnRow[groupByColumn]=r[groupByColumn].ToString();
            returnRow["Adet"]=viewResult.Count;
            //Son olarak satırı tabloya ekliyorum
            returnTable.Rows.Add(returnRow);
        }
        return returnTable;
    }
}


        Bu kadar yazdıktan sonra hadi ne haliniz varsa görün demiycem elbette, şimdi bunu örnek bir uygulamada kullanarak ne işe yaradığını tam olarak anlatayım, Yeni bir WindowsApplication projesi açıp, yukardaki Classımızı orya ekliyelim, ardında forma 2 DataGrid 3 adette button ekleyip aşşağıdaki kodları yazıyoruz,



/

/yukardaki classtan bir instance oluşturuyorum
SharpSql csSql=new SharpSql();

//verileri getir butonu
private void button1_Click(object sender, System.EventArgs e)
{
    SqlConnection cn=new SqlConnection(
                "Data Source=.;
                 Initial Catalog=Northwind;
                 Integrated Security=SSPI;"
);
    SqlCommand cmd=new SqlCommand("select * from [Order Details]",cn);
    SqlDataAdapter da=new SqlDataAdapter(cmd);
    DataSet ds=new DataSet();
    da.Fill(ds,"siparisDetay");
    dataGrid1.DataSource=ds.Tables[0];
}

//Distinct butonu

private void button2_Click(object sender, System.EventArgs e)
{
    /*
     * tekrar eden kayıtlar eleniyor

     * ve sonuç bir DataTable olarak döndüğü için
     * DataSet'e ekliyorum
     */
    string distinctColumn;
    distinctColumn=((DataTable)dataGrid1.DataSource).Columns[dataGrid1.CurrentCell.ColumnNumber].ColumnName ;
    dataGrid2.DataSource=csSql.Distinct((DataTable)dataGrid1.DataSource ,distinctColumn);
}

//Group By butonu

private
void button3_Click(object sender, System.EventArgs e)
{
    /* 
     * Gruplandırmada kullanılacak sütun ve 
     * toplamların alınacağı sütunları ekliyorum
     * sonuç yine datatable olarak döndüğünden
     * onuda dataset'e ekliyorum
     */
    SharpSql.GroupColumnCollection col=new SharpSql.GroupColumnCollection();
    SharpSql.GroupColumn obj;
    obj=new SharpSql.GroupColumn("UnitPrice");
    col.Add(obj);
    obj=new SharpSql.GroupColumn("Quantity");
    col.Add(obj);                
    string groupColumn;
    groupColumn=((DataTable)dataGrid1.DataSource).Columns[dataGrid1.CurrentCell.ColumnNumber].ColumnName;
    dataGrid2.DataSource=csSql.GroupBy((DataTable)dataGrid1.DataSource,col,groupColumn);
}


        Programı çalıştırdığımızda öncelikle Verileri Getir butonunu tıklıyoruz gelen veriler sadece select sorgumusun sonuçları, ProductID sütununa göre sıralayınca anlaşılacaktır zaten, ProductID stünunu seçip Distinct butonuna tıklayınca sonuçlar dataGrid2'de görünecektir tekrar edilen satırlar elendi



    Group By butonuna tıladığımızda ise bu defata, kodlarımızda belirttiğimiz Quantity ve UnitPrice sütunlarındaki değerlerin ProductID'ye göre toplamları görünecektir




       Benimde en çok ihtiyaç duyduğum kısım GroupBy kısmıydı ve bu işimi oldukça gördü umarım sizlerinde işine yarar (biraz uzun oldu sanki )



Yorum (3) :: Yorum yaz! :: Bağlantı

<- Son Sayfa :: Sonraki Sayfa ->

Hakkımda

.Net teknolojileri, # Sharp Dilleri ve olan biten ne varsa

Kategoriler

Arkadaşlarım

hepgittik