JavaScript ve .NET'te JavaScript Nesne Gösterimine (JSON) Giriş
JavaScript ve .NET'te JavaScript Nesne Gösterimine (JSON) Giriş
Atif Aziz, Scott Mitchell
Şubat 2007
Aşağıdakiler cihazlar için geçerlidir:
JSON
Ajax
Özet: Bu makalede, Ajax stili web uygulamaları için daha uygun standartlaştırılmış bir veri değişimi biçimi sağlayan açık ve metin tabanlı bir veri değişimi biçimi olan JavaScript Nesne Gösterimi (veya JSON) ele alınmaktadır. (22 yazdırılan sayfa)
İçindekiler
Giriş
JavaScript'te Değişmez Değer Gösterimini Anlama
JSON ile XML karşılaştırması
JavaScript ile JSON İletileri Oluşturma ve Ayrıştırma
.NET Framework JSON ile çalışma
Sonuç
Başvurular
Bu makalenin kaynak kodunu indirin.
Giriş
Uzak bir bilgisayarla iletişim kuracak bir uygulama tasarlarken bir veri biçimi ve değişim protokolü seçilmelidir. Çeşitli açık, standartlaştırılmış seçenekler vardır ve ideal seçim, uygulama gereksinimlerine ve önceden var olan işlevlere bağlıdır. Örneğin, SOAP tabanlı web hizmetleri verileri BIR SOAP zarfı içinde sarmalanmış xml yükünde biçimlendirin.
XML birçok uygulama senaryosu için iyi çalışsa da, bunu diğerleri için idealden daha az hale getiren bazı dezavantajları vardır. XML'nin genellikle idealden daha az olduğu bir alan, Ajax stili web uygulamalarıdır. Ajax, tam sayfa geri göndermeler yerine web sunucusuna bant dışı ve basit çağrılar kullanarak daha hızlı bir kullanıcı deneyimi sağlayan etkileşimli web uygulamaları oluşturmak için kullanılan bir tekniktir. Bu zaman uyumsuz çağrılar javascript kullanılarak istemcide başlatılır ve verileri biçimlendirmeyi, bir web sunucusuna göndermeyi ve döndürülen verileri ayrıştırmayı ve bunlarla çalışmayı içerir. Çoğu tarayıcı XML oluşturabilir, gönderebilir ve ayrıştırabilir, ancak JavaScript Nesne Gösterimi (veya JSON), Ajax stili web uygulamaları için daha uygun olan standartlaştırılmış bir veri değişimi biçimi sağlar.
JSON açık, metin tabanlı bir veri değişimi biçimidir (bkz . RFC 4627). XML gibi, insan tarafından okunabilir, platformdan bağımsızdır ve geniş bir uygulama kullanılabilirliğine sahip olur. JSON standardına göre biçimlendirilmiş veriler hafiftir ve JavaScript uygulamaları tarafından inanılmaz bir şekilde ayrıştırılabilir ve bu da Ajax web uygulamaları için ideal bir veri değişimi biçimidir. Öncelikle veri biçimi olduğundan JSON yalnızca Ajax web uygulamalarıyla sınırlı değildir ve uygulamaların yapılandırılmış bilgileri metin olarak değiştirmesi veya depolaması gereken hemen hemen her senaryoda kullanılabilir.
Bu makalede JSON standardı, JavaScript ile ilişkisi ve XML ile karşılaştırması incelendi. .NET için açık kaynak JSON uygulaması jayrock ele alınıyor ve JSON iletileri oluşturma ve ayrıştırma örnekleri JavaScript ve C# dilinde sağlanıyor.
JavaScript'te Değişmez Değer Gösterimini Anlama
Değişmez değerler, sabit tamsayı değeri 4 veya "Hello, World" dizesi gibi sabit değerleri tam anlamıyla ifade etmek için programlama dillerinde kullanılır. Değişmez değerler, denetim deyimindeki bir koşulun parçası, işlev çağrılırken giriş parametresi, değişken ataması vb. gibi ifadelere izin verilen çoğu dilde kullanılabilir. Örneğin, aşağıdaki C# ve Visual Basic kodu x değişkenini 42 sabit tamsayı değeriyle başlatır.
int x = 42; // C#
Dim x As Integer = 42 ' Visual Basic
Farklı programlama dilleri, farklı türlerdeki değişmez değerleri sağlar. Çoğu programlama dili, tamsayılar, kayan nokta sayıları, dizeler ve Boole gibi skaler türler için en azından değişmez değerleri destekler. JavaScript ile ilgili ilginç olan, skaler türlere ek olarak diziler ve nesneler gibi yapılandırılmış türler için değişmez değerleri de desteklemesidir. Bu özellik, dizilerin ve nesnelerin isteğe bağlı oluşturulması ve başlatılması için terse söz dizimini sağlar.
JavaScript'teki dizi değişmez değerleri sıfır veya daha fazla ifadeden oluşur ve her ifade dizinin bir öğesini temsil eder. Dizi öğeleri köşeli ayraç ([]) içine alınır ve virgülle sınırlandırılır. Aşağıdaki örnek, yedi kıtanın adlarını tutan yedi dize öğesi içeren bir diziyi tanımlar :
var continents = ["Europe", "Asia", "Australia", "Antarctica", "North
America", "South America", "Africa"];
alert(continents[0] + " is one of the " + continents.length + "
continents.");
Şimdi bunu, değişmez değer gösterimi olmadan JavaScript'te diziyi nasıl oluşturacağınız ve başlatacağınız ile karşılaştırın:
var continents = new Array();
continents[0] = "Europe";
continents[1] = "Asia";
continents[2] = "Australia";
continents[3] = "Antarctica";
continents[4] = "North America";
continents[5] = "South America";
continents[6] = "Africa";
Nesne değişmez değeri, bir nesnenin üyelerini ve değerlerini tanımlar. Nesne üyeleri ve değerleri listesi küme ayraçları ({}) içine alınır ve her üye virgülle sınırlandırılır. Her üyenin içinde ad ve değer iki nokta üst üste (:) ile sınırlandırılır. Aşağıdaki örnek bir nesne oluşturur ve "123 Anywhere St.", "Springfield" ve "99999" değerlerine sahip Address, City ve PostalCode adlı üç üyeyle başlatır.
var mailingAddress = {
"Address" : "123 Anywhere St.",
"City" : "Springfield",
"PostalCode" : 99999
};
alert("The package will be shipped to postal code " +
mailingAddress.PostalCode);
Şimdiye kadar sunulan örneklerde dizi ve nesne değişmez değerleri içinde dize ve sayısal değişmez değerlerin kullanılması gösterilmektedir. Ayrıca, dizi öğelerinin ve nesne üyesi değerlerinin kendilerinin de nesne ve dizi sabit değerlerini kullanabilmesi için gösterimi yinelemeli olarak kullanarak grafın tamamını ifade edebilirsiniz. Örneğin, aşağıdaki kod parçacığı, bir diziyi üye (PhoneNumbers) olarak içeren bir nesneyi gösterir ve burada dizi bir nesne listesinden oluşur.
var contact = {
"Name": "John Doe",
"PermissionToCall": true,
"PhoneNumbers": [
{
"Location": "Home",
"Number": "555-555-1234"
},
{
"Location": "Work",
"Number": "555-555-9999 Ext. 123"
}
]
};
if (contact.PermissionToCall)
{
alert("Call " + contact.Name + " at " + contact.PhoneNumbers[0].Number);
}
Not JavaScript için değişmez değer desteği hakkında daha ayrıntılı bir açıklama, Değişmez Değerler bölümünün altındaki Core JavaScript 1.5 Kılavuzu'nda bulunabilir.
JavaScript Değişmez Değerlerinden JSON'a
JSON, JavaScript'teki değişmez nesne gösteriminin bir alt kümesinden oluşturulmuş bir veri değişimi biçimidir. Değişmez değerler için JavaScript tarafından kabul edilen söz dizimi çok esnek olsa da, JSON'un çok daha katı kuralları olduğuna dikkat etmek önemlidir. Örneğin, JSON standardına göre nesne üyesinin adı geçerli bir JSON dizesi olmalıdır . JSON'daki bir dize tırnak içine alınmalıdır . Öte yandan JavaScript, üye adı ayrılmış bir JavaScript anahtar sözcüğüyle çakışmadığı sürece nesne üye adlarının tırnak işaretleri veya kesme işaretleri ile sınırlandırılmasına veya alıntının tamamen atılmasına izin verir. Benzer şekilde, JSON'daki bir dizi öğesi veya nesne üyesi değeri çok sınırlı bir kümeyle sınırlıdır. Ancak JavaScript'te dizi öğeleri ve nesne üyesi değerleri işlev çağrıları ve tanımlar dahil olmak üzere hemen hemen tüm geçerli JavaScript ifadelerine başvurabilir!
JSON'un çekiciliği basitliğidir. JSON standardına göre biçimlendirilmiş bir ileti, tek bir en üst düzey nesneden veya diziden oluşur. Dizi öğeleri ve nesne değerleri nesneler, diziler, dizeler, sayılar, Boole değerleri (true ve false) veya null olabilir. Bu, kısaca JSON standardıdır! Gerçekten bu kadar basit. Standardın daha resmi bir açıklaması için bkz. www.json.org veya RFC 4627 .
JSON'un önemli noktalarından biri, tarih/saat değişmez değerinin olmamasıdır. Birçok kişi, JSON ile ilk karşılaştıkları zaman bunu öğrendiklerinde şaşırır ve hayal kırıklığına uğrar. Tarih/saat değişmez değerinin olmamasının basit açıklaması (çözümleyici veya değil), JavaScript'te de hiç bulunmamasıdır: JavaScript'te tarih ve saat değerleri desteği tamamen Date nesnesi aracılığıyla sağlanır. Veri biçimi olarak JSON kullanan uygulamaların çoğu genellikle tarih ve saat değerlerini ifade etmek için bir dize veya sayı kullanma eğilimindedir. Bir dize kullanılıyorsa, genellikle ISO 8601 biçiminde olmasını bekleyebilirsiniz. Bunun yerine bir sayı kullanılırsa, genellikle dönem 1 Ocak 1970 (UTC) gece yarısı olarak tanımlandığı dönemden bu yana Evrensel Eşgüdümlü Saat (UTC) cinsinden milisaniye sayısı anlamına gelir. Bu yalnızca bir kuraldır ve JSON standardının bir parçası değildir. Başka bir uygulamayla veri alışverişinde bulunuyorsanız, JSON değişmez değeri içinde tarih ve saat değerlerini nasıl kodladiğini görmek için belgelerine bakmanız gerekir. Örneğin, Microsoft'un ASP.NET AJAX açıklanan kuralların hiçbirini kullanmaz. Bunun yerine, .NET DateTime değerlerini JSON dizesi olarak kodlar; burada dizenin içeriği \/Date(ticks)\/ olur ve burada değer işaretleri dönem (UTC) tarihinden bu yana milisaniyeleri temsil eder. Dolayısıyla 29 Kasım 1989, 04:55:30 UTC değeri "\/Date(628318530718)\/" olarak kodlanmıştır. Bu oldukça karmaşık kodlama seçiminin ardındaki bazı gerekçeler için bkz. "AJAX'ın JSON tarih ve saat dizesi ASP.NET içinde."
JSON ile XML karşılaştırması
Hem JSON hem de XML, metin tabanlı, insan tarafından okunabilen veri değişimi biçiminde yerel, bellek içi nesneleri temsil etmek için kullanılabilir. Ayrıca, iki veri değişim biçimi izomorfiktir; bir biçimde metin verildiğinde, eşdeğeri diğerinde düşünülebilir. Örneğin, Yahoo!'nun genel olarak erişilebilen web hizmetlerinden birini çağırırken, yanıtın XML veya JSON olarak biçimlendirilip biçimlendirilmeyeceğini bir querystring parametresi aracılığıyla belirtebilirsiniz. Bu nedenle, bir veri değişimi biçimine karar verirken, birini gümüş madde işareti olarak diğerinin üzerine seçmek basit bir mesele değildir, bunun yerine belirli bir uygulama için en iyi seçim olmasını sağlayan özelliklerin hangi biçime sahip olduğu önemlidir. Örneğin, XML'in kökenleri belge metnini işaretlemektir ve bu alanda çok iyi parlama eğilimindedir (XHTML'de olduğu gibi). JSON ise programlama dili türlerine ve yapılarına dayanmaktadır ve bu nedenle yapılandırılmış veri alışverişi için daha doğal ve hazır bir eşleme sağlar. Aşağıdaki tablo, bu iki başlangıç noktasının ötesinde XML ve JSON'un temel özelliklerini anlamanıza ve karşılaştırmanıza yardımcı olur.
XML ile JSON Arasındaki Temel Özellik Farkları
Özellik | XML | JSON |
---|---|---|
Veri türleri | Veri türleriyle ilgili herhangi bir bilgi sağlamaz. Tür bilgileri eklemek için XML Şemasına güvenilmelidir. | Skaler veri türleri ve diziler ve nesneler aracılığıyla yapılandırılmış verileri ifade etme olanağı sağlar. |
Diziler için destek | Dizilerin kurallarla ifade edilmesi gerekir, örneğin dizilerin içeriğini iç öğeler olarak modelleyen bir dış yer tutucu öğesinin kullanılması yoluyla. Genellikle, dış öğe iç öğeler için kullanılan adın çoğul biçimini kullanır. | Yerel dizi desteği. |
Nesneler için destek | Nesneler genellikle özniteliklerin ve öğelerin karma kullanımı yoluyla kurallarla ifade edilmeli. | Yerel nesne desteği. |
Null destek | Xml örneği belgesindeki öğelerde xsi:nil kullanılmasını ve buna karşılık gelen ad alanının içeri aktarılmasını gerektirir. | Null değeri yerel olarak tanır. |
Yorumlar | Yerel destek ve genellikle API'ler aracılığıyla kullanılabilir. | Desteklenmez. |
Ad alanları | Belgeleri birleştirirken ad çakışması riskini ortadan kaldıran ad alanlarını destekler. Ad alanları, mevcut XML tabanlı standartların güvenli bir şekilde genişletilmesine de olanak sağlar. | Ad alanı kavramı yoktur. Adlandırma çakışmaları genellikle nesneleri iç içe yerleştirerek veya nesne üye adında bir ön ek kullanılarak önlenir (uygulamada ilki tercih edilir). |
Biçimlendirme kararları | Karmaşık. Uygulama türlerini XML öğeleri ve öznitelikleriyle eşlemeye karar vermek için daha fazla çaba gerektirir. Öğe odaklı veya öznitelik odaklı yaklaşımın daha iyi olup olmadığı konusunda tartışmalar oluşturabilir. | Basit. Uygulama verileri için çok daha doğrudan eşleme sağlar. Tek özel durum, tarih/saat değişmez değeri olmaması olabilir. |
Boyut | Özellikle biçimlendirmeye yönelik öğe odaklı bir yaklaşım kullanıldığında, belgelerin boyutu uzun olma eğilimindedir. | Söz dizimi çok terstir ve alanın büyük bölümünün temsil edilen veriler tarafından kullanıldığı (doğru şekilde) biçimlendirilmiş metin verir. |
JavaScript'te ayrıştırma | Metni JavaScript nesnelerine geri eşlemek için bir XML DOM uygulaması ve ek uygulama kodu gerektirir. | Metni ayrıştırmak için ek uygulama kodu gerekmez; JavaScript'in değerlendirme işlevini kullanabilir. |
Öğrenme eğrisi | Genellikle çeşitli teknolojilerin aynı anda kullanılmasını gerektirir: XPath, XML Şeması, XSLT, XML Ad Alanları, DOM vb. | JavaScript veya diğer dinamik programlama dillerinde arka planı olan geliştiricilere zaten tanıdık gelen çok basit teknoloji yığını. |
JSON, nispeten yeni bir veri değişimi biçimidir ve XML'nin bugün sahip olduğu benimseme veya satıcı desteği yıllarına sahip değildir (JSON hızla yakalansa da). Aşağıdaki tabloda XML ve JSON alanlarındaki geçerli durum vurgulanır.
XML ve JSON Arasındaki Destek Farkları
Destek | XML | JSON |
---|---|---|
Araçlar | Birçok sektör satıcısı tarafından yaygın olarak sunulan olgun bir araç kümesine sahiptir. | Düzenleyiciler ve biçimlendiriciler gibi zengin araç desteği azdır. |
Microsoft .NET Framework | .NET Framework sürüm 1.0'dan bu yana çok iyi ve olgun destek. XML desteği, Temel Sınıf Kitaplığı'nın (BCL) bir parçası olarak sağlanır. Yönetilmeyen ortamlar için MSXML vardır. | AJAX ASP.NET kapsamındaki ilk uygulama dışında şu ana kadar hiçbiri yok. |
Platform ve dil | Ayrıştırıcılar ve biçimlendiriciler birçok platformda ve dilde (ticari ve açık kaynak uygulamaları) yaygın olarak kullanılabilir. | Ayrıştırıcılar ve biçimlendiriciler zaten birçok platformda ve birçok dilde kullanılabilir. İyi bir başvuru kümesi için json.org başvurun. Şimdilik çoğu uygulama açık kaynak projeler olma eğilimindedir. |
Tümleşik dil | Sektör satıcıları şu anda tam anlamıyla diller içinde destek denemeleri gerçekleştirmektedir. Daha fazla bilgi için Microsoft'un LINQ projesine bakın. | Yalnızca JavaScript/ECMAScript'te yerel olarak desteklenir. |
Not İki tablo da karşılaştırma noktalarının kapsamlı bir listesi olarak tasarlanmamıştır. Her iki veri biçimlerinin de karşılaştırılabildiği başka açılar da vardır, ancak bu önemli noktaların ilk izlenim oluşturmak için yeterli olması gerektiğini düşündük.
JavaScript ile JSON İletileri Oluşturma ve Ayrıştırma
Veri değişimi biçimi olarak JSON kullanılırken, iki yaygın görev yerel ve bellek içi gösterimi JSON metin gösterimine dönüştürür ve tam tersi de geçerlidir. Ne yazık ki, yazma sırasında JavaScript, belirli bir nesneden veya diziden JSON metni oluşturmak için yerleşik işlevler sağlamaz. Bu yöntemlerin 2007'de ECMAScript standardının dördüncü sürümüne eklenmesi beklenmektedir. Bu JSON biçimlendirme işlevleri JavaScript'e resmi olarak eklenene ve popüler uygulamalarda yaygın olarak kullanılabilene kadar adresinden indirilebilen http://www.json.org/json.jsbaşvuru uygulama betiğini kullanın.
Bu yazının yazılması sırasındaki en son yinelemesinde, www.json.org'daki json.js betiği dizi, dize, Boole, nesne ve diğer JavaScript türlerine JSONString() işlevleri ekler. Skaler türler için toJSONString() işlevleri (Sayı ve Boole gibi) oldukça basittir çünkü yalnızca örnek değerinin dize gösterimini döndürmeleri gerekir. Örneğin Boole türü için toJSONString() işlevi, değer true ise "true" dizesini, aksi takdirde "false" dizesini döndürür. Dizi ve Nesne türleri için toJSONString() işlevleri daha ilginçtir. Dizi örnekleri için, içerilen her öğenin toJSONString() işlevi sırayla çağrılır ve sonuçlar her sonucu sınırlandırmak için virgüllerle birleştirilir. Köşeli ayraç içine alınmış son çıkış. Benzer şekilde, Nesne örnekleri için her üye numaralandırılır ve toJSONString() işlevi çağrılır. Üye adı ve değerinin JSON gösterimi ortada iki nokta üst üste ile birleştirilir; her üye adı ve değer çifti virgülle sınırlandırılır ve çıkışın tamamı küme ayraçları içine alınır.
toJSONString() işlevlerinin net sonucu, herhangi bir türün tek bir işlev çağrısıyla JSON biçimine dönüştürülmesidir. Aşağıdaki JavaScript bir Array nesnesi oluşturur ve açıklayıcı amaçlar için ayrıntılı ve değişmez olmayan yöntemi kullanarak yedi String öğesini kasten ekler. Ardından dizilerin JSON gösterimini görüntüler:
// josn.js must be included prior to this point
var continents = new Array();
continents.push("Europe");
continents.push("Asia");
continents.push("Australia");
continents.push("Antarctica");
continents.push("North America");
continents.push("South America");
continents.push("Africa");
alert("The JSON representation of the continents array is: " +
continents.toJSONString());
Şekil 1. toJSONString() işlevi, JSON standardına göre biçimlendirilmiş diziyi yayar.
JSON metnini ayrıştırma daha da kolaydır. JSON yalnızca JavaScript değişmez değerlerinin bir alt kümesi olduğundan, kaynak JSON metnini JavaScript kaynak kodu olarak ele alan değerlendirme (expr) işlevi,
kullanılarak bellek içi bir gösterime ayrıştırılabilir.
değerlendirme işlevi, giriş olarak geçerli bir JavaScript kodu dizesi kabul eder ve ifadeyi değerlendirir. Sonuç olarak, JSON metnini yerel bir gösterime dönüştürmek için gereken tek kod satırı aşağıdaki gibidir:
var value = eval( "(" + jsonText + ")" );
Not Fazladan parantezler kullanıldığında , değerlendirmenin koşulsuz olarak kaynak girişe bir ifade gibi davranması sağlanır. Bu özellikle nesneler için önemlidir. "{}" dizesi (boş bir nesne anlamına gelir) gibi bir nesneyi tanımlayan JSON metni içeren bir dizeyle değerlendirmeyi çağırmaya çalışırsanız, ayrıştırılan sonuç olarak tanımsız sonucunu döndürür. Parantezler, JavaScript ayrıştırıcısını bir deyim bloğunu tanımlayan küme ayraçları yerine bir Nesne örneğinin değişmez değeri olarak üst düzey küme ayraçlarını görmeye zorlar. Bu arada, üst düzey öğe bir dizi ise aynı sorun oluşmaz ( değerlendirme("[1,2,3]"). Ancak tekdüzenlik açısından JSON metninin çağrı yapılmadan önce her zaman parantez içine alınması gerekir , böylece kaynağın nasıl yorumlanması gerektiği konusunda bir belirsizlik olmaz.
Değişmez değer gösterimi değerlendirilirken, değişmez değer söz dizimine karşılık gelen bir örnek döndürülür ve değere atanır. Bir dizi için değişmez değer gösterimini ayrıştırmak ve sonuçta elde edilen diziyi değişken kıtalara atamak için değerlendirme işlevini kullanan aşağıdaki örneği göz önünde bulundurun.
var arrayAsJSONText = '["Europe", "Asia", "Australia", "Antarctica",
"North America", "South America", "Africa"]';
var continents = eval( arrayAsJSONText );
alert(continents[0] + " is one of the " + continents.length + "
continents.");
Elbette, uygulamada değerlendirilen JSON metni yukarıdaki örnekte olduğu gibi sabit kodlanmış olmak yerine bir dış kaynaktan gelir.
Değerlendirme işlevi, geçirilen ifadeyi körü körüne değerlendirir. Bu nedenle güvenilir olmayan bir kaynak, JSON verilerini oluşturan değişmez değer gösterimiyle birlikte veya karma olarak tehlikeli olabilecek JavaScript'i içerebilir. Kaynağa güvenilemediği senaryolarda, JSON metnini parseJSON() işlevini (json.js bulunan) kullanarak ayrıştırmanızı kesinlikle öneririz:
// Requires json.js
var continents = arrayAsJSONText.parseJSON();
parseJSON() işlevi de değerlendirme kullanır, ancak yalnızca arrayAsJSONText içindeki dize JSON metin standardına uygunsa. Bunu akıllı bir normal ifade testi kullanarak yapar.
.NET Framework JSON ile çalışma
JSON metni kolayca oluşturulabilir ve javascript kodundan ayrıştırılabilir. Bu kod, bu kodun bir parçasıdır. Ancak, JSON ASP.NET bir web uygulamasında kullanıldığında, sunucu tarafı kodu büyük olasılıkla Visual Basic veya C# dilinde yazıldığından yalnızca tarayıcı JavaScript desteğinden yararlanıyor.
ASP.NET için tasarlanan çoğu Ajax kitaplığı, JSON metnini program aracılığıyla oluşturma ve ayrıştırma desteği sağlar. Bu nedenle, bir .NET uygulamasında JSON ile çalışmak için bu kitaplıklardan birini kullanmayı göz önünde bulundurun. Birçok açık kaynak ve üçüncü taraf seçeneği vardır ve Microsoft'un ASP.NET AJAX adlı kendi Ajax kitaplığı da vardır.
Bu makalede, ortak yazar Atif Aziz tarafından oluşturulan Microsoft .NET Framework için açık kaynak JSON uygulaması olan Jayrock'u kullanan örneklere göz atacağız. AJAX ASP.NET yerine Jayrock kullanmayı üç nedenden dolayı seçtik:
- Jayrock açık kaynaktır ve gerektiğinde genişletmeyi veya özelleştirmeyi mümkün hale getirir.
- Jayrock ASP.NET 1.x, 2.0 ve Mono uygulamalarında kullanılabilirken, ASP.NET AJAX yalnızca ASP.NET sürüm 2.0 içindir.
- Jayrock'un kapsamı JSON ve JSON-RPC ile sınırlıdır ve ilki bu makalenin ana odağıdır. ASP.NET AJAX, JSON metni oluşturma ve ayrıştırma konusunda bazı destek içerse de, birincil amacı ASP.NET'da uçtan uca Ajax stili web uygulamaları oluşturmak için zengin bir platform sunmaktır. Ana odağınız JSON olduğunda ek ziller ve ıslıklar dikkatinizi dağıtabilir.
Jayrock kullanarak .NET'te JSON ile çalışmak, .NET Framework XmlWriter, XmlReader ve XmlSerializer sınıfları aracılığıyla XML ile çalışmaya benzer. Jayrock'ta bulunan JsonWriter, JsonReader, JsonTextWriter ve JsonTextReader sınıfları XmlWriter, XmlReader, XmlTextWriter ve XmlTextReader .NET Framework sınıflarının semantiğini taklit eder. Bu sınıflar, düşük ve akış odaklı bir düzeyde JSON ile birlikte çalışma için kullanışlıdır. Bu sınıfları kullanarak, JSON metni bir dizi yöntem çağrısı aracılığıyla parça parça oluşturulabilir veya ayrıştırılabilir. Örneğin, WriteNumber(number)JsonWriter sınıf yönteminin kullanılması, JSON standardına göre sayının uygun dize gösterimini yazar. JsonConvert sınıfı, .NET türleri ve JSON arasında dönüştürme için Dışarı ve İçeri Aktarma yöntemleri sunar. Bu yöntemler sırasıyla Seri Hale Getirme ve SeriDurumdan Çıkarma XmlSerializer sınıf yöntemlerinde bulunana benzer bir işlevsellik sağlar.
JSON Metni Oluşturma
Aşağıdaki kod, kıtalardan oluşan bir dize dizisi için JSON metni oluşturmak üzere JsonTextWriter sınıfını kullanmayı göstermektedir. Bu JSON metni oluşturucuya geçirilen bir TextWriter örneğine gönderilir ve bu örnekte konsoldan çıkış akışı olur (ASP.NET bunun yerine Response.Output kullanabilirsiniz):
using (JsonTextWriter writer = JsonTextWriter(Console.Out))
{
writer.WriteStartArray();
writer.WriteString("Europe");
writer.WriteString("Asia");
writer.WriteString("Australia");
writer.WriteString("Antarctica");
writer.WriteString("North America");
writer.WriteString("South America");
writer.WriteString("Africa");
writer.WriteEndArray();
}
JsonWriter sınıfı WriteStartArray, WriteString ve WriteEndArray yöntemlerine ek olarak WriteNumber, WriteBoolean, WriteNull gibi diğer JSON değer türlerini yazmak için yöntemler sağlar. WriteStartObject, WriteEndObject ve WriteMember yöntemleri bir nesne için JSON metnini oluşturur. Aşağıdaki örnekte, "JavaScript'te Değişmez Gösterimi Anlama" bölümünde incelenen kişi nesnesi için JSON metninin oluşturulması gösterilmektedir:
private static void WriteContact() { using (JsonWriter w = new JsonTextWriter(Console.Out)) { w.WriteStartObject(); // { w.WriteMember("Name"); // "Name" : w.WriteString("John Doe"); // "John Doe", w.WriteMember("PermissionToCall"); // "PermissionToCall" : w.WriteBoolean(true); // true, w.WriteMember("PhoneNumbers"); // "PhoneNumbers" : w.WriteStartArray(); // [ WritePhoneNumber(w, // { "Location": "Home", "Home" // "Number": "555-555-1234"); // "555-555-1234" }, WritePhoneNumber(w, // { "Location": "Work", "Work", // "Number": "555-555-9999"); // "555-555-9999" } w.WriteEndArray(); // ] w.WriteEndObject(); // } } } private static void WritePhoneNumber(JsonWriter w, string location, string number) { w.WriteStartObject(); // { w.WriteMember("Location"); // "Location" : w.WriteString(location); // "...", w.WriteMember("Number"); // "Number" : w.WriteString(number); // "..." w.WriteEndObject(); // } }
Belirtilen bir .NET türünü JSON metnine seri hale getirmek için JsonConvert sınıfındaki Export ve ExportToString yöntemleri kullanılabilir. Örneğin, JsonTextWriter sınıfını kullanarak yedi kıtanın dizisi için JSON metnini el ile oluşturmak yerine, aşağıdaki JsonConvert.ExportToString çağrısı aynı sonuçları üretir:
string[] continents = { "Europe", "Asia", "Australia", "Antarctica", "North America", "South America", "Africa" }; string jsonText = JsonConvert.ExportToString(continents);
JSON Metnini Ayrıştırma
JsonTextReader sınıfı, JSON metninin belirteçlerini temeli Read olan ayrıştırmak için çeşitli yöntemler sağlar. Read yöntemi her çağrıldığında, ayrıştırıcı bir dize değeri, sayı değeri, nesne üye adı, bir dizinin başlangıcı vb. olabilecek bir sonraki belirteci kullanır. Uygun olduğunda, geçerli belirtecin ayrıştırılan metnine Text özelliği aracılığıyla erişilebilir. Örneğin, okuyucu Boole verilerinin üzerinde oturuyorsa, Text özelliği gerçek ayrıştırma değerine bağlı olarak "true" veya "false" döndürür.
Aşağıdaki örnek kod, yedi kıtanın adlarını içeren bir dize dizisinin JSON metin gösteriminde ayrıştırmak için JsonTextReader sınıfını kullanır. "A" harfiyle başlayan her kıta konsola gönderilir:
string jsonText = @"[""Europe"", ""Asia"", ""Australia"", ""Antarctica"",
""North America"", ""South America"", ""Africa""]";
using (JsonTextReader reader = new JsonTextReader(new
StringReader(jsonText)))
{
while (reader.Read())
{
if (reader.TokenClass == JsonTokenClass.String &&
reader.Text.StartsWith("A"))
{
Console.WriteLine(reader.Text);
}
}
}
Not Jayrock'taki JsonTextReader sınıfı oldukça liberal bir JSON metin ayrıştırıcısıdır. Aslında RFC 4627'de yer alan kurallara göre geçerli JSON metni olarak kabul edilenden çok daha fazla söz dizimine izin verir. Örneğin , JsonTextReader sınıfı, JavaScript'te beklediğiniz gibi tek satırlı ve çok satırlı açıklamaların JSON metninde görünmesini sağlar. Tek satırlı açıklamalar eğik çizgiyle (//) başlar ve çok satırlı açıklamalar eğik çizgi star (/*) ile başlar ve star eğik çizgiyle (*/) biter. Tek satırlı açıklamalar, Unix stili yapılandırma dosyaları arasında yaygın olan karma/pound işaretiyle (# ) bile başlayabilir. Tüm örneklerde açıklamalar ayrıştırıcı tarafından tamamen atlanır ve API aracılığıyla hiçbir zaman gösterilmez. JavaScript'te olduğu gibi , JsonTextReader bir JSON dizesinin kesme işareti (') tarafından sınırlandırılmasına izin verir. Ayrıştırıcı, bir dizi nesnesinin veya öğesinin son üyesinden sonra fazladan virgülü bile tolere edebilir.
Tüm bu eklemelerle bile JsonTextReader uyumlu bir ayrıştırıcıdır! Öte yandan JsonTextWriter yalnızca standart uyumlu katı JSON metni üretir. Bu, genellikle sağlamlık sorumlusu olarak kullanılanları izler ve şöyle ifade eder: "Yaptığınız işte muhafazakar olun; diğerlerinden kabul ettiğiniz şeyde liberal olun."
JSON metnini doğrudan bir .NET nesnesine dönüştürmek için çıkış türünü ve JSON metnini belirterek JsonConvert sınıfı içeri aktarma yöntemini kullanın. Aşağıdaki örnekte bir JSON dize dizisinin .NET dize dizisine dönüştürülmesi gösterilmektedir:
string jsonText = @"[""Europe"", ""Asia"", ""Australia"", ""Antarctica"", ""North America"", ""South America"", ""Africa""]"; string[] continents = (string[]) JsonConvert.Import(typeof(string[]), jsonText);
Burada, RSS XML akışını alan, XmlSerializer kullanarak bir .NET türüne seri durumdan çıkaran ve sonra JsonConvert kullanarak nesneyi JSON metnine dönüştüren (XML'deki RSS'yi JSON metnine etkili bir şekilde dönüştüren) daha ilginç bir dönüştürme örneği verilmiştir:
XmlSerializer serializer = new XmlSerializer(typeof(RichSiteSummary)); RichSiteSummary news; // Get the MSDN RSS feed and deserialize it... using (XmlReader reader = XmlReader.Create("https://msdn.microsoft.com/rss.xml")) news = (RichSiteSummary) serializer.Deserialize(reader); // Export the RichSiteSummary object as JSON text, emitting the output to // Console.Out. using (JsonTextWriter writer = new JsonTextWriter(Console.Out)) JsonConvert.Export(news, writer);
NotRichSiteSummary ve ilgili türlerinin tanımı bu makaleye eşlik eden örneklerde bulunabilir.
ASP.NET'de JSON kullanma
JSON ile JavaScript'te ve jayrock kullanarak .NET Framework içinde çalışmanın yollarını inceledikten sonra, tüm bu bilgilerin nerede ve nasıl uygulanabileceğine ilişkin pratik bir örne dönmenin zamanı geldi. web tarayıcısından ASP.NET sayfasına (veya sayfadaki belirli bir denetime) bant dışı çağrılar yapma işlemini basitleştiren ASP.NET 2.0'daki istemci betiği geri çağırma özelliğini göz önünde bulundurun. Tipik bir geri çağırma senaryosu sırasında, tarayıcıdaki istemci tarafı betiği bir sunucu tarafı yöntemiyle bazı işlemler için verileri paketler ve web sunucusuna geri gönderir. Sunucudan yanıt verilerini aldıktan sonra istemci, tarayıcı görüntüsünü güncelleştirmek için bu verileri kullanır.
Not Daha fazla bilgi için ASP.NET 2.0'da MSDN Dergisi'nin Betik Geri Çağırmaları makalesine bakın.
İstemci geri çağırma senaryosundaki zorluk, istemci ve sunucunun yalnızca bir dizeyi ileri geri gönderebileceğidir. Bu nedenle, değiştirilecek bilgiler gönderilmeden önce yerel, bellek içi bir gösterimden bir dizeye dönüştürülmeli ve alındığında dizeden yerel, bellek içi gösterimine geri ayrıştırılmalıdır. ASP.NET 2.0'daki istemci betik geri çağırma özelliği, değiştirilen veriler için belirli bir dize biçimi gerektirmez ve yerel bellek içi ile dize gösterimleri arasında dönüştürme için yerleşik işlevler sağlamaz; dönüştürme mantığını kendi seçtiği bir veri değişimi biçimine göre uygulamak geliştiriciye bağlıdır.
Aşağıdaki örnekte, bir istemci betiği geri çağırma senaryosunda veri değişimi biçimi olarak JSON'un nasıl kullanılacağı gösterilmektedir. Özellikle örnek, açılan listedeki kategorilerin listesini sağlamak için Northwind veritabanındaki verileri kullanan bir ASP.NET sayfasından oluşur; seçili kategorideki ürünler madde işaretli listede görüntülenir (bkz. Şekil 3). İstemci tarafında açılan liste her değiştirildiğinde, tek öğesi seçili CategoryID olan bir dizi geçirilir.
Not JSON standardı herhangi bir JSON metninin kökü olarak bir nesneye veya diziye sahip olmasını gerektirdiğinden, seçilen CategoryID'yi tek öğesi (yalnızca CategoryID yerine) içeren bir dizi geçiriyoruz. Elbette istemcinin JSON metnini sunucuya geçirmesi gerekmez; bu örnekte yalnızca seçilen CategoryID değerini dize olarak geçirmesini sağlayabilirdik. Ancak, geri çağırmanın hem istek hem de yanıt iletilerinde JSON metni göndermeyi göstermek istedik.
Page_Load olay işleyicisindeki aşağıdaki kod, Categories DropDownList Web denetimini yapılandırır, böylece değiştirildiğinde GetProductsForCategory işlevi çağrılır ve seçilen açılan liste değeri geçirilir. Bu işlev, geçirilen açılan liste değeri sıfırdan büyükse istemci betiği geri çağrısını başlatır:
// Add client-side onchange event to drop-down list
Categories.Attributes["onchange"] = "Categories_onchange(this);";
// Generate the callback script
string callbackScript = ClientScript.GetCallbackEventReference(
/* control */ this,
/* argument */ "'[' + categoryID + ']'",
/* clientCallback */ "showProducts",
/* context */ "null");
// Add the Categories_onchange function
ClientScript.RegisterClientScriptBlock(GetType(),
"Categories_onchange", @"
function Categories_onchange(sender)
{
clearResults();
var categoryID = sender.value;
if (categoryID > 0)
{
" + callbackScript + @"
}
}", true);
Geri çağırmayı çağıran JavaScript kodunu oluşturmak için kullanılan ClientScriptManager sınıfındaki GetCallBackEventReference yöntemi aşağıdaki imzaya sahiptir:
public string GetCallbackEventReference (
Control control,
string argument,
string clientCallback,
string context,
)
bağımsız değişkeni parametresi, geri çağırma sırasında istemciden web sunucusuna hangi verilerin gönderileceğini belirtir ve clientCallback parametresi, geri çağırma tamamlandığında çağrılacak istemci tarafı işlevinin adını belirtir (showProducts). GetCallBackEventReference yöntem çağrısı aşağıdaki JavaScript kodunu oluşturur ve işlenmiş işaretlemeye ekler:
WebForm_DoCallback('__Page','[' + categoryID +
']',showProducts,null,null,false)
'[' + categoryID + ']' , geri çağırma sırasında sunucuya geçirilen değerdir (tek öğeli bir dizi, categoryID) ve showProducts ise geri çağırma döndürdüğünde yürütülen JavaScript işlevidir.
Sunucu tarafında, geri çağırmaya yanıt olarak yürütülen yöntem, gelen JSON metnini ayrıştırmak ve giden JSON metnini biçimlendirmek için Jayrock'tan JsonConvert sınıfını kullanır. Özellikle, seçilen kategoriyle ilişkili ürünlerin adları alınır ve dize dizisi olarak döndürülür.
// Deserialize the JSON text into an array of integers int[] args = (int[]) JsonConvert.Import(typeof(int[]), eventArgument); // Read the selected CategoryID from the array int categoryID = args[0]; // Get products based on categoryID
NorthwindDataSet.ProductsRow[] rows = Northwind.Categories.FindByCategoryID(categoryID).GetProductsRows();// Load the names into a string array
string[] productNames = new string[rows.Length]; for (int i = 0; i < rows.Length; i++) { productNames[i] = rows[i].ProductName;}
// Serialize the string array as JSON text and return it to the client
return JsonConvert.ExportToString(productNames);
NotJsonConvert sınıfı iki kez kullanılır: eventArgument içindeki JSON metnini bir tamsayı dizisine dönüştürmek ve ardından dize dizisi productNames'i istemciye dönmek üzere JSON metnine dönüştürmek için kullanılır. Alternatif olarak, burada JsonReader ve JsonWriter sınıflarını kullanabilirdik, ancak JsonConvert , ilgili veriler nispeten küçük olduğunda ve mevcut türlerle kolayca eşlendiğinde aynı işi oldukça iyi yapar.
Veriler sunucu tarafından döndürülürken, GetCallBackEventReference yönteminden belirtilen JavaScript işlevi çağrılır ve dönüş değeri geçirilir. ShowProducts adlı bu JavaScript yöntemi, ProductOutputdiv> öğesine başvurarak< başlar. Ardından JSON yanıtını ayrıştırarak her dizi öğesi için liste öğesi içeren sıralanmamış bir listeyi dinamik olarak ekler. Seçili kategori için hiçbir ürün döndürülmezse, bunun yerine ilgili bir ileti görüntülenir.
function showProducts(arg, context) { // Dump the JSON text response from the server. document.forms[0].JSONResponse.value = arg; // Parse JSON text returned from callback. var categoryProducts = eval("(" + arg + ")"); // Get a reference to the <div> ProductOutput. var output = document.getElementById("ProductOutput"); // If no products for category, show message. if (categoryProducts.length == 0) { output.appendChild(document.createTextNode( "There are no products for this category...")); } else { // There are products, display them in an unordered list. var ul = document.createElement("ul"); for (var i = 0; i < categoryProducts.length; i++) { var product = categoryProducts[i]; var li = document.createElement("li"); li.appendChild(document.createTextNode(product)); ul.appendChild(li); } output.appendChild(ul); } }
Şekil 2'de olayların sırası gösterilirken Şekil 3 bu örneği uygulamada gösterir; kodun tamamı bu makale indirmesine eklenmiştir.
Şekil 2: İstemci seçilen CategoryID değerini bir dizideki tek öğe olarak gönderir ve sunucu ilişkili ürün adlarından oluşan bir dizi döndürür.
Şekil 3: Ürünler, seçili kategorinin içindeki madde işaretli bir listede görüntülenir.
Sonuç
JSON, JavaScript programlama dilindeki değişmez değer gösteriminin bir alt kümesini temel alan basit, metin tabanlı bir veri değişimi biçimidir. Uygulama veri yapıları için kısa bir kodlama sağlar ve genellikle Ajax stili web uygulamaları gibi veri alışverişinde bulunan uygulamalardan birinde veya her ikisinde javascript uygulamasının kullanılabildiği senaryolarda kullanılır. JSON'un amacı anlamak, benimsemek ve uygulamak için basitliğidir. JSON, JavaScript veya zengin değişmez değer gösterimi (Python ve Ruby gibi) için benzer desteğe sahip diğer programlama dilleri hakkında bilgi sahibi olan geliştiriciler için neredeyse hiç öğrenme eğrisi içermez. JavaScript kodunda JSON metnini ayrıştırmak yalnızca değerlendirme işlevini çağırarak gerçekleştirilebilir ve JSON metni oluşturmak, adresinde http://www.json.org/json.jssağlanan json.js betiğiyle çok kolaydır.
Tüm büyük platformlarda ve çerçevelerde JSON ile çalışmaya yönelik çok sayıda kitaplık vardır. Bu makalede ,NET uygulamalarında JSON metni oluşturmaya ve ayrıştırmaya yönelik açık kaynak bir kitaplık olan Jayrock'ı inceledik. Jayrock ASP.NET 1.x, 2.0 ve Mono uygulamalarında kullanılabilir. ASP.NET AJAX benzer JSON işlevleri sunar, ancak yalnızca ASP.NET 2.0 uygulamaları için geçerlidir.
Mutlu Programlama!
Başvurular
- ASP.NET AJAX
- AJAX Uzantılarıyla İstemci Tarafı Web Hizmeti Çağrıları
- Core JavaScript 1.5 Kılavuzu
- eval(expr) işlevi
- Jayrock
- JSON.org
- ASP.NET Betik Geri Çağırmaları
- RFC 4627
Ajax mı, AJAX mı?
Ajax terimi ilk olarak Jesse James Garrett tarafından web uygulamalarının stilini ve son derece etkileşimli web uygulamaları yapmak için kullanılan bir dizi teknolojiyi açıklamak için kullanılmıştır. Geçmişte, Ajax terimi web'de AJAX kısaltması olarak yayılıyor, yani Zaman Uyumsuz JavaScript ve XML. Ancak zamanla, çoğu uygulama daha basit ve daha verimli bir alternatif olarak JSON'a geçtiğinden, insanlar AJAX'taki "X"in arka planda web sunucusuyla iletişim kurmak için kullanılan temel veri biçimini çok temsil ettiğini fark etti. Bu nedenle, AJAJ gibi biraz dil bükücü olan bir kısaltma yerine kısaltma genellikle AJAX kısaltması yerine Ajax teriminin lehine kullanımdan kaldırılmaktadır.
Bu yazı sırasında, bir ve aynı anlama gelen "AJAX" ve "Ajax" karma ve geniş bir kullanım görmeyi bekleyin. Bu makalede "Ajax terimi" ile takıldık. Bununla birlikte, Ajax tarzı uygulamalara olanak sağlayan çerçeveler sağlayan ticari ürünler, benzer bir temizlik maddesi ürününden ayırt etmek ve olası ticari marka veya yasal uyuşmazlıkları önlemek için kısaltma biçimini kullanma eğilimindedir.
ASP.NET AJAX: JSON tarih ve saat dizesinin içinde
ASP.NET'daki AJAX JSON serileştiricisi , bir DateTime örneğini JSON dizesi olarak kodlar. Yayın öncesi döngüleri sırasında, ASP.NET AJAX "@ticks@" biçimini kullandı ve burada keneler 1 Ocak 1970'ten bu yana Evrensel Eşgüdümlü Saat 'te (UTC) milisaniye sayısını temsil ediyor. UTC'de 29 Kasım 1989, 04:55:30 gibi bir tarih ve saat "@62831853071@" olarak yazılır. Basit ve basit olsa da, bu biçim serileştirilmiş tarih ve saat değeri ile serileştirilmiş tarih gibi görünen ancak seri durumdan çıkarılacak bir dize arasında ayrım yapamaz. Sonuç olarak, ASP.NET AJAX ekibi "\/Date(ticks)\/" biçimini benimseyerek bu sorunu çözmek için son sürümde bir değişiklik yaptı.
Yeni biçim, yanlış yorumlama şansını azaltmak için küçük bir hileye dayanır. JSON'da, bir dizedeki eğik çizgi (/) karakteri, tam olarak gerekli olmasa bile ters eğik çizgiyle (\) kaçılabilir. Bundan yararlanan ASP.NET AJAX ekibi, JavaScriptSerializer'ı değiştirerek bir DateTime örneğini "\/Date(ticks)\/" dizesi olarak yazdı. İki eğik çizginin kaçışı yüzeyseldir, ancak JavaScriptSerializer için önemlidir. JSON kurallarına göre,
"
\/Date(ticks)\/"
teknik olarak /Date(ticks)/"
ile eşdeğerdir"
, ancak JavaScriptSerializer öncekini DateTime, ikincisini dize olarak seri durumdan çıkaracaktır. Bu nedenle, ön sürümlerden daha basit "@ticks@" biçimine kıyasla belirsizlik olasılığı çok daha azdır.
Özel Teşekkürler
Bu makaleyi MSDN'ye göndermeden önce, makalenin yazım denetlemesine yardımcı olan ve içerik, dil bilgisi ve yön hakkında geri bildirim sağlayan bir dizi gönüllü vardı. İnceleme sürecine birincil katkıda bulunanlar arasında Douglas Crockford, Eric Schönholzer ve Milan Negovan yer alıyor.
Yazarlar Hakkında
Atif Aziz, Skybow AG'de baş danışmandır. Burada asıl odak noktası müşterilerin .NET geliştirme platformunda çözümleri anlamasına ve oluşturmasına yardımcı olmaktır. Atif, konferanslarda konuşarak ve teknik yayınlar için makaleler yazarak Microsoft geliştirici topluluğuna düzenli olarak katkıda bulunur. InETA konuşmacısı ve en büyük İsviçre .NET Kullanıcı Grubu başkanıdır. Adresine adresinden atif.aziz@skybow.com veya adresinden ulaşabilirsiniz http://www.raboof.com.
Altı ASP/ASP.NET kitabının yazarı ve 4GuysFromRolla.com kurucusu Scott Mitchell, 1998'den beri Microsoft web teknolojileriyle çalışmaktadır. Scott bağımsız bir danışman, eğitmen ve yazar olarak çalışmaktadır. Blogu mitchell@4guysfromrolla.com aracılığıyla veya adresinden ulaşabilirsiniz: http://ScottOnWriting.net.