Günümüzde çoğu AJAX uygulamasında veri transferi için JSON formatı kullanılıyor. ASP.NET programcılığı tarafında biz farkında olmasak da PageMethod'lar, Web Servisleri veya WCF Servisleri sunucudan JavaScript istemciye asenkron (AJAX) veri taşırken JSON ile çalışıyor. ASP.NET dışındaki dünyaya da baktığımızda tabi ki bu kural geçerliliğini koruyor, örneğin bugün twitter.com kendi uygulamalarından dışarıya asenkron veri aktarırken JSON formatını kullanıyor. Peki Silverlight 2.0 ile salt AJAX mantığından kurtularak artık Web Servislerimizi veya WCF servislerimizi doğrudan asenkron olarak kullanabildiğimize göre karşımıza eski JSON kaynakları gelirse ne yapacağız?
.NET nesnelerinden JSON oluşturmak.
Hikayenin tersinden başlayalım ve ilk olarak istemci tarafında JSON verisi nasıl yaratırız onu inceleyelim. Zaten genelde harici bir web servisinden JSON verisi alacaksanız büyük ihtimal ile elinizdeki hazır bir JSON verisini de web servisine göndermek durumunda kalacaksınız. Bu gibi bir durumda rahatlıkla elimizdeki .NET nesnelerini JSON formatına çevirebiliyor olmalıyız.
Silverlight 2.0 Beta 1 ile beraber gelen sınıflardan system.runtime.serialization.json.datacontractjsonserializer sınıfını kullanacağız. Bu sınıfı normal şartlarda kullanmak isterseniz herhangi bir Silverlight uygulamasında Intellisense ile bulma şansınız olmayacaktır. Söz konusu sınıf harici olarak System.ServiceModel.Web.dll dosyası içerisinde kendisini projemize referans olarak almamızı bekliyor. Gerekli referansı projeye ekledikten sonra rahatlıkla JSON işlemlerini tamamen istemci tarafında yürütebiliyoruz.
Uygulamamızda bir öğrencinin adını ve soyadını taşıyacak bir Ogrenci sınıfı kullanacağız. JSON ile çeviri işlemleri yaparken elimizdeki çevireceğimiz nesnenin tipinin belirli şekilde tanımlanmış olması gerekiyor. O nedenle hemen aşağıdaki kod ile tipimizi tanımlayalım.
Public Class Ogrenci
Private Padi As String
Public Property Adi() As String
Get
Return Padi
End Get
Set(ByVal value As String)
Padi = value
End Set
End Property
Private PSoyadi As String
Public Property Soyadi() As String
Get
Return PSoyadi
End Get
Set(ByVal value As String)
PSoyadi = value
End Set
End Property
Sub New()
End Sub
Sub New(ByVal adi As String, ByVal soyadi As String)
Me.Adi = adi
Me.Soyadi = soyadi
End Sub
End Class
Bu basit işlemi tamamladıktan sonra uygulamamıza üç adet metin kutusu ve iki de düğme yerleştirelim. Bu metin kutularından ikisi öğrencinin adının ve soyadının gözükeceği yer, diğeri ise yarattığımız JSON verisinin yazdırılacağı konum olacak. Düğmelerimizi de işlemleri yapmak için kullanacağız.
<UserControl x:Class="JSON.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<TextBox Height="31" HorizontalAlignment="Left" Margin="22,19,0,0" VerticalAlignment="Top" Width="151" Text="Adı" x:Name="Adi1"/>
<TextBox Height="26" HorizontalAlignment="Left" Margin="22,54,0,0" VerticalAlignment="Top" Width="151" Text="Soyadı" x:Name="Soyadi1"/>
<TextBox Margin="22,142,23,19" Text="TextBox" x:Name="Sonuc"/>
<Button Height="29" HorizontalAlignment="Right" Margin="0,99,97,0" x:Name="Dugme2" VerticalAlignment="Top" Width="102" Content="JSON'dan Al"/>
<Button Height="29" HorizontalAlignment="Left" Margin="45,99,0,0" x:Name="Dugme1" VerticalAlignment="Top" Width="102" Content="JSON Yarat"/>
</Grid>
</UserControl>
İlk olarak Dugme1 nesnesinin arkasına gerekli kodları yazarak metin kutuları içerisinden öğrencinin adını ve soyadını alıp bir öğrenci nesnesi yaratalım. Sonrasında da bu nesneyi JSON verisine çevirerek Sonuc adındaki metin kutusuna yazdıralım.
Dim Cevirici As New System.Runtime.Serialization.Json.DataContractJsonSerializer(GetType(Ogrenci))
Dim Veri As New IO.MemoryStream
Cevirici.WriteObject(Veri, New Ogrenci(Adi1.Text, Soyadi1.Text))
Sonuc.Text = Text.Encoding.UTF8.GetString(Veri.ToArray, 0, Veri.Length)
Cevirici adını verdiğim nesne bir DataContractJsonSerializer nesnesi. Bu nesnenin WriteObject metodunu kullanarak elimizdeki uygun bir .NET nesnesini JSON formatına çevirebiliyoruz. WriteObject metodu toplamda iki parametre alıyor; bunlardan ilki çeviri işlemi esnasında oluşan JSON verisinin yazdırılacağı Stream nesnesi, diğeri ise çevrilecek olan nesnenin ta kendisi. Ben bu örnekte bir MemoryStream kullandım. Son olarak eldeki Stream'i de bir metne çevirerek Sonuc adındaki metin kutusu içerisine yazdırıyoruz.
Böylece uygulamamızda dinamik olarak JSON yaratma sorununu çözmüş olduk. Tamamen istemci tarafında rahatlıkla yarattığımız .NET nesnelerini JSON formatına çevirebiliyoruz. Şimdi de tam tersi bir senaryoya göz atalım.
JSON verisinden .NET nesneleri yaratmak
Bir önceki bölümde kullandığımız örneği aynen kullanmaya devam edelim. Bu sefer de tam tersi bir işlem yaparak Sonuc adındaki metin kutusu içerisine yazılan JSON verisini okuyarak içerisinde öğrencinin adını ve soyadını alıp diğer metin kutularının içerisine yerleştirelim.
Dim Cevirici As New System.Runtime.Serialization.Json.DataContractJsonSerializer(GetType(Ogrenci))
Dim Veri As New IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(Sonuc.Text))
Dim GenelOgrenci = CType(Cevirici.ReadObject(Veri), Ogrenci)
Adi1.Text = GenelOgrenci.Adi
Soyadi1.Text = GenelOgrenci.Soyadi
Her zamanki gibi ilk olarak Cevirici nesnemizi Ogrenci tipinden yaratıyoruz. Bu sefer DataContractJsonSerializer sınıfının ReadObject metodunu kullanacağız. ReadObject metodu okuyacağı veriyi bir Stream olarak istediği için Sonuc adındaki metin kutusu içerisindeki metinden ilk önce bir Byte dizisi sonra da bu diziden bir MemoryStream yaratıyoruz. Aldığımız MemoryStream'i Cevirici nesnemizin ReadObject metoduna verdiğimizde söz konusu metod bize bir Object döndürüyor. Doğal olarak JSON verisi içerisindeki nesnenin hangi .NET nesnesine denk geldiğini bilme şansı yok. O nedenle biz elle casting yaparak aldığımız Object tipindeki değişkeni Ogrenci tipine değiştiriyor ve gerekli verileri alarak diğer metin kutularının içerisine yerleştiriyoruz.
Her iki uygulamayı da bir örnek projede yaptığımızda ilk önce metin kutularına veri girerek JSON verisini yaratabiliyor sonrasında da JSON verisini Sonuc metin kutusunda elle değiştirip tekrar diğer metin kutularına güncel değerlerin aktarılabilmesi için DeSerialize işleminin yapılmasını sağlayabiliyoruz.
Uygulamamızın tam kodu aşağıdaki şekilde sonlanıyor.
Partial Public Class Page
Inherits UserControl
Public Sub New()
InitializeComponent()
End Sub
Public Class Ogrenci
Private Padi As String
Public Property Adi() As String
Get
Return Padi
End Get
Set(ByVal value As String)
Padi = value
End Set
End Property
Private PSoyadi As String
Public Property Soyadi() As String
Get
Return PSoyadi
End Get
Set(ByVal value As String)
PSoyadi = value
End Set
End Property
Sub New()
End Sub
Sub New(ByVal adi As String, ByVal soyadi As String)
Me.Adi = adi
Me.Soyadi = soyadi
End Sub
End Class
Private Sub Dugme1_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Dugme1.Click
Dim Cevirici As New System.Runtime.Serialization.Json.DataContractJsonSerializer(GetType(Ogrenci))
Dim Veri As New IO.MemoryStream
Cevirici.WriteObject(Veri, New Ogrenci(Adi1.Text, Soyadi1.Text))
Sonuc.Text = Text.Encoding.UTF8.GetString(Veri.ToArray, 0, Veri.Length)
End Sub
Private Sub Dugme2_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Dugme2.Click
Dim Cevirici As New System.Runtime.Serialization.Json.DataContractJsonSerializer(GetType(Ogrenci))
Dim Veri As New IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(Sonuc.Text))
Dim GenelOgrenci = CType(Cevirici.ReadObject(Veri), Ogrenci)
Adi1.Text = GenelOgrenci.Adi
Soyadi1.Text = GenelOgrenci.Soyadi
End Sub
End Class
Hepinize kolay gelsin.