Eski versiyonlarla derlenmiş kontrollerin NET 3.5 ile uyumsuzluğunu gidermek
Bilindiği üzere .Net Framework v.3.5 çıkalı hayli zaman oluyor ve projelerimizi yavaş yavaş upgrade ediyoruz. Microsoft, geriye uyumluluk adına her zaman başarılı işler yapsa da bazen kodlarımız içinde ufak tefek güncellemeler yapmamız kaçınılmaz olabiliyor. Lafı dolandırmadan yaşadığım hadiseye ve çözümüne odaklanmak istiyorum.
Asp.Net 2.0 + Ajax 1.0 ile geliştirdiğim bir web projem var ve bu projeyi .net 3.5'a upgrade etmeye karar verdim. Upgrade süreci sorunsuz gerçekleşse de sayfayı test ettiğimde bazı kontrollerimin çalışmadığını farkettim. ( Modüler çalımayı seven birisi olarak, kendime özel kontroller (custom control) geliştiriyorum ve bunları farklı projelerde kullanıyorum. Kontrolleri .Net 2.0 ile yazmış ve derlemiştim. ) Sorunun ne olduğunu bulmak adına, proje referanslarımın geçerli olmayabileceğini düşündüm ve 2.0 ile 3.5 arasında hangi system assembly'lerinin sürümlerinin değiştiğini araştırdım. Sorun tam da buradan kaynaklanıyordu : Kontrollerim System.Web.Extensions (1.1.0.0) ve System.Web.Extensions.Design (1.1.0.0)'e karşı derlenmişti; oysa .net 3.5 ile bu assembly'ler 3.5.0.0 versiyonuna yükseltilmişti.
Bu durumda aklıma gelen ilk çözüm, kontrollerimi .net 3.5 framework ile yeniden derlemek oldu. Kontrollerin kaynak kodları olduğu için bunu gerçekleştirmek çocuk oyuncağıydı; fakat ya kaynak kod elimde olmasaydı? Microsoft mühendislerinin bunu atlamayacağına emin olduğum için, Google'a (in Google we trust) sordum ve cevabımı aldım. Microsoft, versiyon problemlerine karşı <assemblyBinding> etiketini geliştirmiş.
Aşağıdaki kodu web.config'e eklerseniz benim yaşadığım sorunu yaşamayacaksınız. Aşağıdaki konfigürasyon kodu, eski versiyonlu assembly referanslarını yenisine yönlendirmek ve yeni versiyonların kullanılmasını sağlamak kadar basit bir mantık üzerine dayanıyor.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
Bu yazıyı okuyarak olası bir 30 dakika kazandınız. Umarın bu süreyi facebook'da pineklemek yerine sevgilinizi, eşinizi, ailenizi vs. aramakla geçirirsiniz. :)
Tips & Tricks : Gizli kalmış web.config parametreleri ve kullanım alanları - Bölüm 1
Bu yazıda uygulamalarımızın konfigürasyon ayarlarını barındıran web.config dosyasının bize sunduğu özelliklerden pek bilinmeyenleri ele alacağız. Web.config de nedir diyenler için kısa bir açıklama yapalım : Web.config, içinde uygulamalarımızın yapılandırma ayarlarını barındıran ve uygulama bazında erişilebilir olan bir konfigürasyon dosyasıdır. Bu dosya uygulamalarımızın yapılandırılması açısından çok kritik bir rol üstlenmektedir. En genel kullanım örneği, veritabanı bağlantı değerlerinin tutulması ve uygulama bazında paylaşılmasıdır.
1. Uygulamalarınıza Xhtml desteğiEğer sayfalarınızı XHTML tabanlı olarak tasarlıyorsanız, web.config dosyanıza ekleyeceğiniz tek satırlık bir parametre ile kontrollerinizin çıktısının xhtml destekli olmasını sağlayabilirsiniz.
Söz konusu durumun gerçekleşmesi için, <
xhtmlConformance mode="...."/> etiketinin <system.web> etiketinin altına yerleştirilmesi yeterlidir.
Sayfanızın DOCTYPE bildirimine göre, <xhtmlConformance
mode="...." /> etiketindeki üç noktalı alanı belirtmelisiniz. mode parametresi üç farklı değer alabilir :
1. Strict : XHTML 1.0 Strict
2. Transitional : XHTML 1.0 Transitional
3. Legacy : Sayfa çıktısını geriye uyumluluk adına ASP.NET 1.1 kontrollerinin çıktısına benzetir.
Bu sayfanın kaynak koduna bakarsanız (
IE : ALT+V+C, Firefox : CTRL + U),
DOCTYPE olarak
strict kullanıldığını göreceksiniz :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Web.config'deki eklenmesi gereken kod aşağıdaki gibi olmalıdır :
<system.web>
....
<xhtmlConformance mode="Strict"/>
....
</system.web>
Önemli not : Ajax uygulamalarınızda <xhtmlConformance mode="Legacy"/> kullanmayın. Aksi halde uygulamanız hata verecektir. Detaylar için
bu adresi ziyaret edebilirsiniz.
2. EnableViewStateMac özelliği ve Viewstate gizliliği
Viewstate nesnesi, asp.net sayfalarımız arasında içerik taşınmasını sağlayan içeriği şifrelenmiş gizli form değerleridir. Asp.net ile kodlanmış bir sayfanın kaynak kodlarına baktığınızda aşağıdaki gibi kodlar görmeniz muhtemeldir.
(Not : EnableViewState özelliği false olarak atanan sayfalarda viewstate değerleri yoktur.)<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTQxNDM3ODE3NA9kFgICAQ9kFg4CAw9k" />
Her ne kadar Viewstate içeriği şifrelenmiş olsa da bu şifreleme sonucu oluşan değer base64-şifreleme (base64-encoded) bir değer olduğu için kolayca çözülebilir. (Google.com üzerinde "viewstate decoder" sözcükleriyle arama yaparsanız, 35.500 sonuç geldiğini görüp şaşırabilirsiniz.)
İçeriğini gizlemek konusunda daha titiz davranan yazılım geliştiricileri, enableViewStateMac özelliği ile viewstate objelerinin güvenliğini arttırabilirler. enableViewStateMac=true olarak belirtilen bir uygulamada, Viewstate objeleri şifrelenir ve veri transferi esnasında
Message Authentication Check (MAC) işlemine tabi tutulur.
Örnek web.config :
<system.web>
<pages validateRequest="true" enableViewStateMac="true" maintainScrollPositionOnPostBack="true">
</system.web>
Önemli olan diğer bir nokta da web.config içerisinde şifreleme için kullanılacak olan machineKey'in belirtilmesidir. <machineKey> elementinin tanımlanması zorunlu olmadığı halde, bunu tanımlamanızı öneriyorum. Bunun nedenlerinden aşağıda bahsedeceğim. Öncelikle web.config içerisinde örnek bir <machineKey> elementinin nasıl tanımlandığını görelim :
<machineKey validationKey="879797B11D0C0DB4646B58EC6A58FF0183716C51EF4F15EFDBFD71FC327360
D689CCFC3CB78D13C6A3064D195F8654BE6D82B92B39C16F85674EBC8D5B6C5C0E" decryptionKey="E7C77D2552DD71F7332E11DFEC8CA052075F645F640C009B" validation="SHA1" />
Genel tanımlama aşağıdaki gibidir :
<machineKey validationKey="AutoGenerate|value[,IsolateApps]" decryptionKey="AutoGenerate|value[,IsolateApps]" validation="SHA1|MD5|3DES"/>
validationKey : Taşınan datayı doğrulamak için kullanılan anahtar.
decryptionKey : Taşınan datayı şifrelemek için kullanılan anahtar
.validation : Şifreleme tipi (MD5 | SHA1 | 3DES)
ValidationKey ve decryptionKey anahtarları "AutoGenerate" olarak tanımlanırsa, Asp.net otomatik bir anahtar üretecektir. Daha önce de söylediğim gibi AutoGenerate özelliğinin kullanılmasını tavsiye etmiyorum.
AutoGenerate özelliğini kullanırsanız ve uygulamanız bir web farm (sunucu çiftliği) üzerinde yayınlanıyorsa ciddi sıkıntılar sizi bekliyor demektir. MachineKey değeri, sunucu kapmasında üretildiği için, bu anahtarla sunucu A üzerinde şifrelenen bir viewstate değeri, sunucu B üzerinde üretilen anahtar ile çözülemez. Böyle bir durum karşısında, Asp.net runtime, viewstate ile taşınan veri için "ViewState is Corrupt or Invalid for this page" uyarısı verecek ve sayfanın çalıştırılmasını sonlandıracaktır.
machineKey anahtarını manual oluşturur ve bu anahtarı içeren web.config dosyalarını sunucular üzerinde yapılandırırsanız, uygulama tüm doğrulama ve şifreleme/çözme işlemleri için aynı anahtarı kullanarak sorunsuzca çalışacaktır.
MachineKey değeri, uygulamanın barındığı sunucunun donanımına, konfigürasyonuna bağlı olmayan ve bu parametrelere dayanarak oluşturulmayan bir anahtardır. Genel kanının aksine fiziksel sunucu (makina) ile üretilen anahtar arasında hiçbir dolaylı ilişki yoktur. machineKey anahtarı oluşturmanın en pratik yolu
http://aspnetresources.com/tools/keycreator.aspx adresindeki
<machineKey> Generator uygulamasını kullanmaktır.
machineKey Msdn dökümanı için
http://msdn2.microsoft.com/en-us/library/w8h3skw9(VS.71).aspx linkini ziyaret edebilirsiniz.
Yazıyı çok uzun tutmamak için bölümlere ayırdım. Bölüm 2 ile seriye devam edeceğiz.
Tips & Tricks : The name 'xxx' does not exist in the current context hatası ve çözümü
Uygulamanızı derlerken hiç
The name 'xxx' does not exist in the current context hatası aldınız mı?
Gecenin bir yarısı Visual Studio 2005 C# derleyicim avazı çıktığı kadar bağırmaya başladı ve ısrarla aşağıdaki hataları verdi :

Doğal olarak aklıma gelen ilk neden, aspx sayfa içindeki isimlendirmelerin bir şekilde değiştiği ve derleyicinin bu nedenle uyarıları sıralamaya başladığı oldu.
Html kodunu içeren aspx dosyasını incelediğim zaman isimlendirmelerin doğru olduğunu gördüm ve sayfayı tekrar derlemeye çalıştım; fakat o da ne? Derleyici hala ısrarla hataları düzelt diyordu.
Yaklaşık 15dk kadar uğraştıktan sonra farkettim ki sorun koddan kaynaklanmıyordu. Search.aspx üzerinde optimizasyon yaparken dosyanın bir yedeğini alıp search - copy.aspx olarak kaydetmiştim.
Her iki dosya da search.aspx.cs dosyasına bağlandığı için derleyici uyarı veriyordu. search - copy.aspx dosyasını projeden çıkarınca (exclude) sorun çözülmüş oldu.
Normal şartlarda daha önce yaşadığım bu olayın çözümünü hatırlamıyor olmamı, bu olayın sabaha karşı 05:30'da gerçekleşmesine bağlıyorum.
Bu problemden çıkarılacak dersler şunlar olmalı :1. Gece yarısı, uykusuz ve dalgın yazılım geliştirmek, içkili araba kullanmaya benziyor. Ne kadar tecrübeli olursanız olun hata yapma oranınız artıyor. Sözü üstada bırakmak gerekirse : "It's hard enough to find an error in your code when you're looking for it; it's even harder when you've assumed your code is error-free." - Steve McConnell
2. Derleyiciler keyfi davranıp sizi sinirden çıldırtmak isteyen yaratıklar değildir, bir hata alıyorsanız sorunu öncelikle kendinizde aramalısınız.
3. Çözüm bazen sorunu anlamaktan daha kısa olabilir.
Visual Studio'nun açılışını hızlandırmak

Hemen hemen tüm .net yazılımcılarının editörü olan visual studio'nun açılış süresini az da olsa kısaltmak mümkün. Bunun için kısayolunuzun sonuna "/nosplash" sözcüğünü eklemeniz yeterli. Bu durumda açılış esnasında vs splash ekranı yok olacak ve editör açılış süresi kısalacaktır.
P.S. Kişisel olarak bu ufak ipucunu uygulamadığımı belirtmek isterim. Nedeni kullandığımın makinanın güçlü donanımı nedeniyle vs.net açılış süresinin zaten çok kısa olması.