Archive for March, 2008
March 25, 2008 at 00:56 · Tags: .net framework, remoting
Remoting Server’ın Çalıştırılması
1. Start menüsü içerisinde bulunan “Run” kısayoluna tıklayın ve karşınıza çıkan ekrana “cmd” yazarak OK butonuna tıklayın.

2. Açılan ekranda command prompt’a cd command’ını kullanarak MyFirstRemotingServer project’inizin bulunduğu klasöre, oradan da sırasıyla “bin” ve “Debug” klasörlerine girin.
3. İlgili klasörlere girdikten sonra command prompt’a “MyFirstRemotingServer.exe” yazarak ENTER tuşuna basın.
4. Bilgisayarınızda herhangi bir firewall uygulaması yüklü olması durumunda karşınıza “MyFirstRemotingServer” uygulamasının internet ve ya network üzerinden bağlantı kabul etmesinin block’landığına dair bir mesaj gelebilir.

5. Bu durumda uygulamanın unblock edilmesi gerekir.
6. Uygulamanın düzgün çalışması durumunda command prompt’ta “Remoting server is running… Press ENTER to exit.” yazısı belirir.
Bu yazıyı gördüğünüzde, yazmış olduğunuz ilk Remoting server’ı başarıyla çalışıyor demektir.
NOT
MyRemotableType object’inin ilk olarak MyFirstRemotableType project’i içerisinde interface olarak yazılmış olmasının amacı Remoting client’ın bu interface’i kullanacak olmasıdır. Class ise MyFirstRemotableServer project’i içerisinde geliştirilmiştir. Böylece Remoting client sürekli olarak interface’i kullanacaktır ve class içerisindeki programmatic değişiklikler sebebiyle, her seferinde Remoting client’larının tamamının yeniden deploy edilmesine gerek kalmayacaktır. Herhangi bir güncelleme durumunda yalnızca Remoting server’ın yeniden deploy edilmesi güncelleştirmeyi sağlayacaktır.
Özet
- Remotable Type’lar Marshal-by-value ve Marshal-by-reference olarak iki şekilde oluşturulabilirler.
- Channel, Remoting server’ı ve Remoting client’ının aralarındaki haberleşme için kullanılan protokole verilen genel isimdir.
- .NET Framework içerisinde HTTP, TCP ve IPC olarak üç adet channel bulunmaktadır. Gerekli görüldüğü durumlarda System.Runtime.Remoting.Channels.IChannelReceiver ve System.Runtime.Remoting.Channels.IChannelSender interface’leri implement edilerek custom channel’lar hazırlanabilir.
- HTTP channel’ı maksimum interoperability’ye sahiptir. TCP channel’ı maksimum efficiency’ye sahiptir. IPC channel’ı network üzerinden iletişim sağlamadığı için yalnızca aynı fiziksel bilgisayar üzerinde bulunan application domain’leri üzerindeki Remoting server ve client’ları arasındaki iletişim için kullanılabilir.
- Formatter, channel üzerinden geçecek olan mesajları ilgili formatter’ın yapısına göre şekillendiren yapıdır.
- .NET Framework içerisinde SoapFormatter ve BinaryFormatter tipinde iki adet formatter bulunmaktadır. Gerekli görüldüğü durumlarda System.Runtime.Remoting.Messaging.IRemotingFormatter interface’ini implement ederek custom formatter’lar hazırlanabilir.
- Remoting server’ları ve Remoting client’ları hem configuration file kullanılarak hem de programmatic olarak configure edilebilmektedir.
March 22, 2008 at 21:21 · Tags: .net framework, remoting
Bu işlemler sonrasında New Project ekranı aşağıdaki şekilde görünür:

NOT
Location property’sinde yazmakta olan “C:\Path\to\Your\Project” path’i seçmiş olduğunuz path’e göre değişiklik gösterektir.
1. OK butonuna tıklayın.
2. Karşınıza “Program.cs” isimli bir dosya açık olacak çıkar.

3. Bu dosyanın ismini Solution Explorer penceresi yardımı ile “MyRemotingServer.cs” olarak değiştirin.

4. Visual Studio “Program.cs” dosyasının ismini değiştirdikten sonra bu dosya içerisindeki “Program” isimli class’ın ismi otomatik olarak “MyRemotingServer” şeklinde değişir. Değişmemesi durumunda class’ın ismini “MyRemotingServer” olarak değiştirin.
5. Solution Explorer penceresindeki References klasörüne sağ tıklayarak “Add Reference” seçeneğine tıklayın.

6. Karşınıza “Add Reference” penceresi çıkar. Bu pencerede “.NET” tab’ındaki “System.Runtime.Remoting” assembly’sini seçin ve OK butonuna tıklayın.

7. MyRemotingServer.cs dosyası içerisinde aşağıdaki namespace’leri import edin:
MyRemotingServer.cs dosyasına import edilecek namespace’lerin import edilişleri
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
8. MyRemotingServer class’ının access modifier’ını public olarak ayarlayın.
MyRemotingServer class’ının “public” access modifier’ına sahip olarak ayarlanması
public class MyRemotingServer
9. Remoting server’ımızı “exe” dosyası ile aynı klasörde bulunacak olan “MyFirstRemotingServer.exe.config” dosyasını okuyarak kendisini configure etmesi için RemotingConfiguration class’ının Configure method’unu kullanın.
RemotingConfiguration.Configure method’unun kullanımı
RemotingConfiguration.Configure("MyFirstRemotingServer.exe.config", false);
10. Remoting server’ınızı ENTER tuşuna basıldığında programı sonlandıracak şekilde ilgili kodu yazın.
Console Application’un ENTER tuşu ile sonlandırılması
Console.WriteLine("Remoting server is running... Press ENTER to exit.");
Console.ReadLine();
11. Solution Explorer ekranında bulunan project’inizin ismine sağ tıklayarak Add menüsünden “New Item…” seçeneğini seçin.

12. Açılan “Add New Item” ekranında “Application Configuration File” template’ini seçin ve Name property’sini “MyFirstRemotingServer.exe.config” olarak değiştirin.

13. Add butonuna tıklayın.
14. “MyFirstRemotingServer.exe.config” isimli dosya otomatik olarak açılacaktır.

15. Configuration dosyasının içeriğini aşağıdaki şekilde değiştirin. Bu configuration dosyasına göre Remoting server’ı TCP protokolü kullanarak, 4444. port üzerinden ve gerekli formatlamaları yaparken BinaryFormatter kullanacak şekilde çalışacak ayrıca oluşturmuş olduğumuz MyRemotableType class’ını host edecektir.
MyFirstRemotingServer.exe.config dosyası içeriği
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown
mode="Singleton"
type="MyFirstRemotingServer.MyRemotableType, MyFirstRemotingServer"
objectUri="MyRemotableType.rem"
/>
</service>
<channels>
<channel ref="tcp" port="4444">
<serverProviders>
<formatter ref="binary"/>
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
16. Solution Explorer penceresindeki References klasörüne sağ tıklayarak “Add Reference” seçeneğine tıklayın.
17. Karşınıza “Add Reference” penceresi çıkar. Bu pencerede “Browse” tab’ını seçerek “MyFirstRemotableType” project’inin bulunduğu klasöre gidin.

18. Bu klasör içerisinde de sırasıyla “bin” ve “Debug” klasörlerine girerek “MyFirstRemotableType.dll” isimli assembly’yi seçin ve OK butonuna tıklayın.

19. Solution Explorer ekranında bulunan project’inizin ismine sağ tıklayarak Add menüsünden “New Item…” seçeneğini seçin.
20. Açılan “Add New Item” ekranında “Application Configuration File” template’ini seçin ve Name property’sini “MyRemotableType.cs” olarak değiştirin.

21. Add butonuna tıklayın.
22. “MyRemotableType.cs” isimli dosya açık olacak gelir.

23. Class’ı ImyRemotableType interface’ini implement edecek şekilde yazın.
MyRemotableType.cs dosyası içeriği
using System;
using MyFirstRemotableType;
namespace MyFirstRemotingServer
{
public class MyRemotableType : MarshalByRefObject, IMyRemotableType
{
int requestCount;
public MyRemotableType()
{
this.requestCount = 0;
}
public DateTime GetServerDateTime()
{
requestCount++;
return System.DateTime.Now;
}
public int RequestCount()
{
return requestCount;
}
}
}
24. Build menüsünü kullanarak project’i build edin.

25. Bu işlem sonrasında Visual Studio’nun sol alt köşesinde “Build succeeded” yazısı belirir.

26. “Add Project” ekranında project’in Location özelliğine atadığınız path’e gidin.
27. Bu path içerisinde bulunan “MyFirstRemotingServer.exe.config” isimli dosyayı yine aynı klasörde bulunan “bin” ve bu klasörün altında bulunan “Debug” klasörünün içerisine, yani “MyFirstRemotingServer.exe” dosyasının bulunduğu klasöre kopyalayın.
Bir sonraki makalede diğer adımlar anlatılacaktır.
March 17, 2008 at 12:29 · Tags: asp.net
In case you get the following exception while trying to run an ASP.NET application, the solution is not as simple as setting the "enableEventValidation" configuration to "false" all the time.
Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
I had such a problem last week. One of my colleagues asked me to check a problem because he could not see it and everything used to work perfectly before. I must confess that I spent hours to find the problem. Even if I set the "enableEventValidation" value to "false", nothing worked and everything started to lose its ViewState data.
Finally, I’ve found that the problem was a forgotten "form" tag within a user control. So, if you have such a problem about losing ViewState unexpectedly and exceptions about Event Validation, double check your code not to have such <form> tags.
March 12, 2008 at 01:56 · Tags: .net framework, remoting
Channel, Formatter, Remotable Type kavramlarının tamamı hakkında bilgi sahibi olduk. Şimdi Remoting server’ı üzerinde çalışacak ve aşağıdaki class structure’ına sahip olacak Remotable Type’ı host edecek Remoting server’ını yazalım.
| Class: MyRemotableType
Access modifier: public |
Access Modifier
|
Return Type |
Name |
Purpose |
| public |
DateTime |
GetServerDateTime |
DateTime class’ının Now property’sini döndürecektir ve RequestCount method’unun döndüreceği requestCount field’ının değerini bir değer arttıracak method’dur. |
| public |
int |
RequestCount |
requestCount variable’ının çalıştırılma zamanındaki değerini geri göndürecek olan method’dur. |
Tablo 3.1.2
Remotable Type’ın Development’ı
1. Visual Studio’yu çalıştırın.
2. File > New menüleri altındaki Project seçeneğini seçin.
3. Visual C# > Windows seçeneği altındaki Class Library proje tipini seçin.
4. Name property’sine MyFirstRemotableType yazın.
5. Location property’sine projeyi oluşturmak istediğiniz klasörün path’ini yazın ve ya Browse seçeneğini kullanarak path’i gösterin.
6. Solution Name property’si otomatik olarak MyFirstRemotableType şeklinde değişir, eğer değişmemiş ise bu property’ye de MyFirstRemotableType yazın.
Bu işlemler sonrasında New Project ekranı aşağıdaki şekilde görünür:

NOT
Location property’sinde yazmakta olan “C:\Path\to\Your\Project” path’i seçmiş olduğunuz path’e göre değişiklik gösterektir.
7. OK butonuna tıklayın.
8. Karşınıza “Class1.cs” isimli bir dosya açık olacak çıkar.

9. Bu dosyanın ismini Solution Explorer penceresi yardımı ile “IMyRemotableType.cs” olarak değiştirin.

10. Visual Studio “Class1.cs” dosyasının ismini değiştirdikten sonra bu dosya içerisindeki “Class1″ isimli class’ın ismi otomatik olarak “IMyRemotableType” şeklinde değişir. Değişmemesi durumunda class’ın ismini “IMyRemotingType” olarak değiştirin.
11. Class’ı interface olarak değiştirin.

12. Interface’in kodunu Tablo 3.1.2′deki method’ları içerecek şekilde, aşağıdaki şekilde yazın.
MyRemotableType.cs dosyası içeriği
using System;
namespace MyFirstRemotableType
{
public interface IMyRemotableType
{
DateTime GetServerDateTime();
int RequestCount();
}
}
13. Build menüsünü kullanarak project’i build edin.

14. Bu işlem sonrasında Visual Studio’nun sol alt köşesinde “Build succeeded” yazısı belirir.

15. Visual Studio’yu kapatın.
Remoting Server’ın Development’ı
1. Visual Studio’yu çalıştırın.
2. File > New menüleri altındaki Project seçeneğini seçin.
3. Visual C# > Windows seçeneği altındaki Console Application proje tipini seçin.
4. Name property’sine MyFirstRemotingServer yazın.
5. Location property’sine projeyi oluşturmak istediğiniz klasörün path’ini yazın ve ya Browse seçeneğini kullanarak path’i gösterin.
6. Solution Name property’si otomatik olarak MyFirstRemotingServer şeklinde değişir, eğer değişmemiş ise bu property’ye de MyFirstRemotingServer yazın.
Bir sonraki makalede diğer adımlar anlatılacaktır.
March 6, 2008 at 00:12 · Tags: .net framework, remoting
Remoting uygulamaları programatik olarak configure edilebileceği gibi, gerekli configuration dosyalarını okumaları sağlanarak da configure edilebilirler (ör: machine.config).
Bir önceki makalemizde (Makale 4: Sunucu Uygulamalarının Çalışma Zamanında Yapılandırılması) gördüğümüz üzere Remoting server’larının channel ismi, port, priority gibi özellikleri bulunmakta. Şimdi uygun bir configuration dosyası hazırlayarak uygulamamızı daha az kod yazarak nasıl configure edebileceğimizi görelim.
İPUCU
Remoting uygulamalarının configuration dosyaları kullanılarak configure edilmesi configuration’larda değişiklik yapılması durumunda uygulamanın yeniden derlenmesine olan ihtiyacı ortadan kaldıracağı için daha avantajlıdır.
Yeni bir Visual Studio projesi oluşturup, proje tipi olarak “Console Application” seçeneğini seçelim ve proje ismini de “ConfigSerAppConfigFile” olarak verelim. Solution içerisine “Class Library” tipinde yeni bir proje daha ekleyelim. Bu class library projesinin ismini “ConfigSerAppCFile.RemObjects” olarak verelim. Oluşturduğumuz class library projesine “Configure a server application programmatically” başlığı altında yaptığımız örnekte kullandığımız “MyRemotableObject” class’ını birebir olarak ekleyelim.
“ConfigSerAppCFile.RemObjects” projesini “ConfigSerAppConfigFile” projesine referans olarak ekledikten sonra console application projemize yeni bir configuration dosyası ekleyerek ismini “ConfigSerAppConfigFile.exe.config” olarak değiştirelim. Bu dosya içeriğini de aşağıdaki şekilde değiştirelim.
ConfigSerAppConfigFile.exe.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel ref="tcp" port="1234">
<serverProviders>
<formatter ref="soap"/>
</serverProviders>
</channel>
</channels>
<service>
<wellknown
mode="Singleton"
type="ConfigSerAppCFile.RemObjects.MyRemotableObject, ConfigSerAppCFile.RemObjects"
objectUri="MyRemotableType.rem"
/>
</service>
</application>
</system.runtime.remoting>
</configuration>
Yukarıdaki kodlarda görmüş olduğunuz gibi channel bilgileri, remotable type bilgileri ve formatter bilgileri configuration dosyaları içerisinde tanımlanabilmektedir.
Bu kodumuzdaki en önemli nokta channel ve formatter tag’ları içerisinde bulunan ref attribute’üdür. Bu attribute machine.config dosyasında tanımlanmış olan bilgilere referans vermek için kullanılır. ref attribute’ünün yerine type attribute’ünün kullanılması durumunda ise ref attribute’ünün kullanılmasına gerek bulunmamaktadır. Örneğin MyCustomChannel isminde bir class oluşturduğunumuzu, bu class’ı daha önce bahsettiğimiz IChannelReceiver interface’inden implement ettiğimizi ve class’ın içerisinde bulunduğu assembly’nin isminin de CustomChannelAssembly olduğunu düşünürseniz, type attribute’ü şu şekilde tanımlanmalıdır:
“type” attribute’ü kullanımı
<channel type="MyCustomChannel,MyCustomChannelAssembly" port="1234">
<serverProviders>
<formatter ref="soap"/>
</serverProviders>
</channel>
Buradaki type attribute’ü kullanımı birebir olarak uygun şekilde geliştirilen formatter’lar için de geçerlidir.
Son olarak da uygulamamızı tanımlamış olduğumuz configuration dosyasını okuyacak ve Remoting configuration’ını kendi kendine yapacak şekile getirelim.
RemotingServer.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace ConfigSerAppConfigFile
{
public class RemotingServer
{
static void Main(string[] args)
{
RemotingConfiguration.Configure("../../ConfigSerAppConfigFile.exe.config", false);
TcpChannel tcpChannel = ChannelServices.RegisteredChannels[0] as TcpChannel;
if (tcpChannel == null)
{
Console.WriteLine("Invalid configuration file...");
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
}
WellKnownServiceTypeEntry[] registeredWellKnownServiceTypes = RemotingConfiguration.GetRegisteredWellKnownServiceTypes();
foreach (WellKnownServiceTypeEntry type in registeredWellKnownServiceTypes)
{
Console.WriteLine("{0} is registered.", type.TypeName);
}
string[] urls = tcpChannel.GetUrlsForUri("MyRemoteObject.rem");
string objectUrl = urls[0];
string objectUri = null;
string channelUri = tcpChannel.Parse(objectUrl, out objectUri);
Console.WriteLine("The URL for the object is {0}.", objectUrl);
Console.WriteLine("The URI for the object is {0}.", objectUri);
Console.WriteLine("The URI for the channel is {0}.", channelUri);
Console.WriteLine("Remoting server is now listening...");
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
}
}
}
Yazmış olduğumuz kodları sırasıyla şu şekilde açıklayalım.
- RemotingConfiguration class’ının sahip olduğu static olarak işaretlenmiş Configure method’unu kullanarak configuration bilgilerimizi barındıran configuration dosyasını okumasını ve Remoting configuration’ını bu dosyadaki bilgiler doğrultusunda yapmasını sağladık.
- Remoting configuration’ı içerisinde “WellKnownService” olarak register edilmiş olan remotable type’ları registeredWellKnownServiceTypes değişkenine atadık.
- registeredWellKnownServiceTypes değişkenini foreach döngüsü içerisine alarak register edilmiş object’lerin TypeName bilgilerini ekrana, sadece bilgi amaçlı olarak, yazdırdık..
- Servisimiz ile ilgili URL ve URI bilgilerini sadece bilgi edinmek amacıyla ekrana yazdırdık.
Visual Studio üzerinde uygulamayı çalıştırdığımızda karşımıza aşağıdaki ekran gelir:

UYARI
Ekran görüntüsü içerisinde görünen IP adresi bilgisayarınızın network konfigürasyonuna göre farklılık gösterebilir.
RemotingServer class’ı içerisinde kullandığımız bazı method’lar ve görevleri aşağıdaki gibidir.
| Method
|
Görev |
| RemotingConfiguration.Configure |
Configuration dosyasının Remoting uygulamasının configuration’ı için yüklenmesini sağlar. Örnek uygulamada verilen path’in başında herhangi bir bilgi olmadığında uygulama configuration dosyasını kendi bulunduğu path içerisinde arayacaktır. Dosyanın bulunamaması durumunda System.IO.FileNotFoundException throw edilir. Yazmış olduğumuz örnekte configuration dosyasının iki üst klasörde olmasından dolayı bu path’in başına “../../” (2 defa nokta, nokta, slash) ekleyerek dosyanın iki üst klasörde aranmasını sağladık. |
| RemotingConfiguration.GetRegisteredWellKnownServiceTypes |
Configuration dosyasında bulunan <service> nodu’u içerisinde register edilen remotable type’ların listesinin alınabileceği method’dur. |
UYARI
Remoting uygulamanızın üzerinde çalışacağı port bilgisini yazarken ilgili port’un başka bir uygulama tarafından kullanılmadığından emin olunuz. Örneğin IIS’in 80. port üzerinde çalıştığını düşünürseniz ve siz de uygulamanızı 80. port üzerinden çalışacak şekilde ayarlarsanız aşağıdaki hata ile karşılaşırsınız:
” System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted “