ASP.NET Web Service Caching

Selamlar,bu inceleme yazımızda keyifli konulardan biri olduğuna inandiğim Web Servislere giriş yapiyoruz,zaman içerisinde umarım bir yazı dizisi haline gelecektir,ilk olarak bir web servis ne işe yarar ondan bahsedelim , cok kolay bir bakiş açisi sağlamak için şöyle düşünebiliriz ki , yapilan işlemlerin sonucunda her platformun anlayabileceği bir şekilde veri taşinmasina yardımcı olmaktadır,her platformun anlayacağı bir veri dili olarak da XML seçilmiştir, genişletilebilir bir yapi olmasi ve kolay çözümlenmesi nedeniyle XML bir standart haline gelmiştir, Web servis in temeli olan XML hakkında yazıları internet üzerinden kolaylıkla bulabilirsiniz , bu yazımızda biz inceleme olarak Web Servis yaratarak onun kullanımına ilişkin noktalara değineceğiz,bir web servis,daha da basitce ifade edilirse,internet üzerinden kullanıma açilmiş,metotlar olarak değerlendirebiliriz,programlama dilimizde metotlari bizim için iş parçaciklari olarak değerlendirdiğimizde , web servisi de herkesin kullanımına açik iş parçaciklari olarak değerlendirebiliriz.Bu metotlarda normal kullandığımız metotlardan farkli olarak WebMethod özelliğine sahiptirler ve çalıştıklarin andan itibaren bir değer üreteceklerse bu değeri XML formatinda üretirler ve servisi kullanan istemci bu değeri kendi referans listesinde bulunan yapi üzerinden veri tipi de dahil olmak üzere yorumlayarak okur,bu özelliklerinin içerisinde değiştirilebilir noktalar bulunmaktadır,bu özellikleri bu yazımızda bulabilirsiniz tabi bir kaç tanesini , örneğin WebMethod özelliğine verilebilecek olan MessageName özelliği , o metodun servisinin yayın yaptiği sayfasında,metoda ait bir açiklama olarak değerlendirilebilir,ben bu yazıda bunun yerine web methodlar da session kullanımı , caching kullanımı ve transaction kullanımına değineceğim.Ilk olarak Caching ile başliyoruz…

visual Studio editörümüzde , File > New > Web Site dedikten sonra , gelen dialog penceresinde , ASP.NET Web Servise seçeneğini seçiyoruz , ve servisimizin

hazırlanma süreci başlamaktadir.Açilişta hello world metodunu görebilirsiniz… [ Servisi IIS üzerinde açiyoruz ]

Web Service Step 1

Gelelim kendi metodumuzla ön bellekleme tekniğini kullanmaya , bunun için bir metot yazıyoruz , bu metot bellekleme yapmayacak özellikte bir metot olacaktır

,onun yanınada ön bellek tekniğini kullanacağımız bir metot daha yaziyoruz, ve iki metodumuzda mutlaka WebMethod özelliğine sahip olmak zorundadır, işte metotlarimiz ..

  1. // Web Method Caching Attribute
  2. [WebMethod(CacheDuration = 20)] // 20 saniye süresince veri ön bellekleme işlemine tabi tutulur,istemci için.
  3. public string GetTime(string Name)
  4. {
  5. return string.Format("{0},Zaman : {1}", Name, DateTime.Now.ToString());
  6. }
  7.  
  8. [WebMethod(MessageName = "ZamanGetir2")]
  9. public string GetTime(string Name, int offsetDay)
  10. {
  11. return string.Format("{0},Zaman : {1}", Name, DateTime.Now.AddDays(offsetDay).ToString());
  12. }

Aynı isimli 2 metot kullandığımız için burada web servisler üzerinde kullanılan metotlarin aynı zamanda aşiri yüklenmesi konusuna da girmiş oluyoruz,aşiri yükleme için MessageName özelliginin kullanılmasi gerekiyor , aynı zamanda servis sınıfımızın üzerinde bulunan özelliklerden biri olan aşağıdaki değeri de değiştiriyoruz :

  1. [WebServiceBinding(ConformsTo = WsiProfiles.None)]

Yukaridaki ki 2 metot da bizler için zaman bilgisi değeri döndürmektedir, bu metotlarin çıktılarının gerçekten ne işe yaradğını görmek için,bir istemci uygulamasi yazmamız gerekmektedir,tabiki bu istemcide , yayın yapılan servisin yayın yaptiği adresi bilmesi gerekecektir..

Web Servisin hizmet vereceği adresi ve hizmet verilen metotlarimizi sayfamız üzerinde görüntüleyelim , bir derleme işlemi sonrası Service.asmx dosyasını tarayici penceresi içerisinde görüntüleme seçeneğini seçersek bu işlemi yapabiliriz.

Web Service Step 2

Bir Console Application açalim ve References bölümüne sağ tiklayarak Service Reference bölümünü seçelim ve burada , servisin adresini yazip Go butonuna basalim , sonrasinda verilen adreste bir servisin olup olmadiği araştirilacaktir,arka planda WSDL dosyası da incelenmektedir yeri gelmişken hatirlatayim , ve servis bulunduğunda bu servise istemci uygulamamizda erişmemiz için bir namespace eki verilmesi beklenecektir ve bizde bu değeri “_AttributesProjectService” olarak verdik.

Web Service Step 3

Gelelim artik istemci uygulamasi içerisinde servisin zaman bilgisi getiren ön bellekleme tekniği kullanılan metotlarini kullanmaya…Istemci uygulamamizin kodlari.

  1. using System;
  2.  
  3. namespace TestProject
  4. {
  5. class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. _AttributesProjectService.ServiceSoapClient client = new TestProject._AttributesProjectService.ServiceSoapClient();
  10.  
  11. for (int i = 0; i < 25; i++)
  12. {
  13. Console.WriteLine("– {0}.Zaman Bilgisi", i + 1);
  14. Console.WriteLine(client.GetTime("ÖnBelleklenen Zaman"));
  15. Console.WriteLine(client.GetTime1("ÖnBelleklenmeyen Zaman",3));
  16. System.Threading.Thread.Sleep(1000);
  17. }
  18.  
  19. Console.Read();
  20. }
  21. }
  22. }

Çıktımız ..

Web Service Step 4

Bir sonraki yazıda , Session ve Transaction ile devam edeceğiz,şimdilik bu kadar…

ASP.NET Exception Management & DataMining

Ulaşılacak saadete kaç kapı daha var isimli sagopa parçasını dinlerken , işyerinde başlayip gece 3 gibi biten bir hikayenin satirlari bunlar (: , konuya giriş olarak hangi konudan bahsedeceğimizi belirtelim , asp.net teknolojilerinde hata kayıt işlemi ve bu işlemin ileride getirebileceği önemli avantajlari göz önünde bulundurarak , olusan her hatayi kayit altina alma işine gireceğiz, bir örnek üzerinde konusacak olursak , bir web projesinde , yazılım tarafı hazırlanıp artık yayına girdikten sonra yazılımcılarının göremedikleri hatalari kullanıcılar fark edebilir ve bunlari birer bir an önce güvenli çıkış butonuna basmalarini hissettirecek hata sayfası ile karşı karşıya kalabilirler.Olusan hatalardan haberdar olmak tabiki cok güzel olacaktır , ve bu hataların türlerini bilmek ayrıca bir avantaj saglayacaktır.Bu avantaja birde sayfanın hangi durumlarinda meydana geldiği bilgisini eklediğimizde , gerçek zamanlı bir yazılımımızın hata takip sistemini hayata geçirmiş oluruz.Bir sayfada hata üretiminin yapısı kontrollerden alinan verilerin yazım hatalarından yada taşma hatalarından kaynaklı istisnai durumlar oluşabilir , yada http://www.bizimsite.com/Sayfa.aspx?Kriter=508 gibi,bir sayfaya talep geldiğinde,58 degerine denk düşen bir kayıt yok ise ve kontroller yapilmamiş ise , sayfa içerisinde bir noktada hata meydana gelecektir , yada querystring bilgisi bir byte cinsinden değişkene alinmaya çalışılıyorsa , taşma hatasi meydana gelecektir , burada oluşacak olan taşma hatası yada nullreference türünden bir istisnai durum ve mesajları biz proje yazarlarına hangi hatayi daha çok yayına verdiğimiz konusunda yardımcı olacaktır.

Örnek içerisinde bir hata meydana geldiğinde , veritabanina kayıt edilen veriler :
1 => WebSite Adi , IP Adresi
2 => Kullanıcı IP Adresi
3 => Hata Mesajı
4 => Hata Sebebi
5 => QueryString’ler ve taşidiklari veriler
6 => Sayfanın klasörü (varsa) , Web Form Sayfasının adı.

Bu verileri kayıt etmek için bize bir veritabani gerekli olacaktır, ve örneğimizde bu iş için Sql Server üzerinde bir veritabanindan yararlanacağız , tablolar arasi ilişkiler olduğu için t-sql kodlarini değilde , sizlerle Database Diagram’ı paylaşiyorum.

ExceptionDB Diagram

ExceptionDB Diagram

Veritabaninda dikkat ettiğimiz husus , cok fazla veri girişi olabileceğinden , yineleyen kayıtlari almamak adina ( özellikle metinsel formatta olanlar ) bir tasarim gerçekleştiriyoruz.Düşünün ki , aynı IP adresinden , aynı web form’a farklı QueryString’ler ile aynı hatalar meydana getirilebilir,bu durumda farklı olan tek şey , hata kayıtı yaparken , açilacak olan kayıta ait sadece yeni querystring key leri olduğunu belirtmeliyiz.

Yazdığımız hata kayıt sınıfımızın kodları …

CustomException.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data.SqlClient;
  4. using System.Collections.Specialized;
  5.  
  6. namespace CustomException
  7. {
  8. public class CustomEx : System.SystemException
  9. {
  10. private static SqlConnection _conn;
  11. private static SqlCommand _cmd;
  12.  
  13. private DateTime _date;
  14. private string _message;
  15. private string _webAddr;
  16. private string _webAddrIP;
  17. private string _userIP;
  18. private string _reason;
  19. private List<string> _urlAddr;
  20. private List<QueryStringValue> _urlQueries;
  21.  
  22. public CustomEx()
  23. {
  24. _conn = new SqlConnection();
  25. _conn.ConnectionString = "Server=YourServer;Database=ExceptionDB;User
  26.  
  27. Id=YourUser;Password=YourPassWord;Trusted_Connection=False;";
  28. _cmd = new SqlCommand();
  29. _cmd.Connection = _conn;
  30. }
  31.  
  32. public CustomEx(string errorMessage,string errorReason,string webSiteIP,string userIP,string[]
  33.  
  34. urlSegments,NameValueCollection queryCollection,string webAddr):this()
  35. {
  36. this._date = DateTime.Now;
  37. this._message = errorMessage;
  38. this._reason = errorReason;
  39.  
  40. /*
  41. SERVER_NAME    www.creacoder.com
  42. LOCAL_ADDR    99.88.77.1907 gibi (:
  43. REMOTE_ADDR    user ip
  44. */
  45.  
  46. _webAddr = webAddr;
  47. _webAddrIP = webSiteIP;
  48. _userIP = userIP;
  49.  
  50. _urlAddr = new List<string>();
  51. for (int i = 0; i < urlSegments.Length; i++)
  52. this._urlAddr.Add(urlSegments[i]);
  53.  
  54. if (queryCollection.Count > 0)
  55. {
  56. this._urlQueries = new List<QueryStringValue>();
  57. for (int i = 0; i < queryCollection.Count; i++)
  58. _urlQueries.Add(new QueryStringValue()
  59. {
  60. Key = queryCollection.Keys[i],
  61. Value = queryCollection[i]
  62. });
  63. }
  64. }
  65.  
  66. public void RegError()
  67. {
  68. Error e = new Error();
  69. _conn.Open();
  70.  
  71. // Step 1 => Record Error Message , if not exists on ErrorMessages table
  72. #region MyRegion
  73. _cmd.CommandText = "select Count(Id) from ErrorMessages where ErrorMessage = @m";
  74. _cmd.Parameters.Add("@m", System.Data.SqlDbType.NVarChar,50).Value = _message;
  75. int messageCount = (int)_cmd.ExecuteScalar();
  76. if (messageCount < 1)
  77. {
  78. // message not exists , new record
  79. _cmd.Parameters.Clear();
  80. _cmd.CommandText = "insert into ErrorMessages (ErrorMessage) values (@m)";
  81. _cmd.Parameters.Add("@m", System.Data.SqlDbType.NVarChar).Value = _message;
  82. _cmd.ExecuteNonQuery();
  83.  
  84. _cmd.Parameters.Clear();
  85. _cmd.CommandText = "select top 1 Id from ErrorMessages order by Id DESC";
  86. e.ErrorID = (int)_cmd.ExecuteScalar();
  87. }
  88. else
  89. {
  90. _cmd.Parameters.Clear();
  91. _cmd.CommandText = "select Id from ErrorMessages where ErrorMessage=@m";
  92. _cmd.Parameters.Add("@m", System.Data.SqlDbType.NVarChar).Value = _message;
  93. e.ErrorID = (int)_cmd.ExecuteScalar();
  94. }
  95. #endregion
  96.  
  97. // Step 2 => Take Date
  98. #region MyRegion
  99. e.ErrorDate = _date;
  100. #endregion
  101.  
  102. // Step 3 => Take Web Address , ex => www.creacoder.com
  103. #region MyRegion
  104. _cmd.Parameters.Clear();
  105. _cmd.CommandText = "select Count(Id) from WebSites where WebSite = @site and IPAddr = @ip";
  106. _cmd.Parameters.Add("@site", System.Data.SqlDbType.NVarChar).Value = _webAddr;
  107. _cmd.Parameters.Add("@ip", System.Data.SqlDbType.NVarChar).Value = _webAddrIP;
  108. int siteCount = (int)_cmd.ExecuteScalar();
  109.  
  110. if (siteCount < 1)
  111. {
  112. // web site not exists , new record
  113.  
  114. _cmd.Parameters.Clear();
  115. _cmd.CommandText = "insert into WebSites (WebSite,IPAddr) values (@p1,@p2)";
  116. _cmd.Parameters.Add("@p1", System.Data.SqlDbType.NVarChar).Value = _webAddr;
  117. _cmd.Parameters.Add("@p2", System.Data.SqlDbType.NVarChar).Value = _webAddrIP;
  118. _cmd.ExecuteNonQuery();
  119.  
  120. _cmd.Parameters.Clear();
  121. _cmd.CommandText = "select top 1 Id from WebSites order by Id DESC";
  122. e.ErrorWebID = (int)_cmd.ExecuteScalar();
  123. }
  124. else
  125. {
  126. _cmd.Parameters.Clear();
  127. _cmd.CommandText = "select Id from WebSites where WebSite = @site and IPAddr = @ip";
  128. _cmd.Parameters.Add("@site", System.Data.SqlDbType.NVarChar).Value = _webAddr;
  129. _cmd.Parameters.Add("@ip", System.Data.SqlDbType.NVarChar).Value = _webAddrIP;
  130. e.ErrorWebID = (int)_cmd.ExecuteScalar();
  131. }
  132. #endregion
  133.  
  134. // Step 4 => WebSiteUrl
  135. #region MyRegion
  136. _cmd.Parameters.Clear();
  137. _cmd.CommandText = "insert into WebSitesUrls (WebSiteID) values (@id)";
  138. _cmd.Parameters.Add("@id", System.Data.SqlDbType.Int).Value = e.ErrorWebID;
  139. _cmd.ExecuteNonQuery();
  140.  
  141. // Url’s web site id recorded…
  142. // Step 5 => this web url’s segments’ recording… so take the last url id
  143.  
  144. _cmd.Parameters.Clear();
  145. _cmd.CommandText = "select top 1 Id from WebSitesUrls order by Id DESC";
  146. e.ErrorUrlID = (int)_cmd.ExecuteScalar();
  147. #endregion
  148.  
  149. // Step 5 => record segments…
  150. #region MyRegion
  151. _cmd.Parameters.Clear();
  152. _cmd.CommandText = "insert into WebSiteUrlSegments (Segment,UrlID) values (@p1,@p2)";
  153. _cmd.Parameters.Add("@p1", System.Data.SqlDbType.NVarChar);
  154. _cmd.Parameters.Add("@p2", System.Data.SqlDbType.Int);
  155.  
  156. foreach (string seg in this._urlAddr)
  157. {
  158. _cmd.Parameters["@p1"].Value = seg;
  159. _cmd.Parameters["@p2"].Value = e.ErrorUrlID;
  160. _cmd.ExecuteNonQuery();
  161. }
  162. #endregion
  163.  
  164. // Step 6 => recording query string parameters… if exists
  165. #region MyRegion
  166. if (_urlQueries != null && _urlQueries.Count > 0)
  167. {
  168. // record keys,,,
  169. foreach (QueryStringValue key in _urlQueries)
  170. {
  171. QueryString q = new QueryString();
  172. #region Insert Key,Value and take KeyID and ValueID
  173. // take KeyID
  174. _cmd.Parameters.Clear();
  175. _cmd.CommandText = "select Count(Id) from WebQueryKeyCollection where QueryKey=@key";
  176. _cmd.Parameters.Add("@key", System.Data.SqlDbType.NVarChar).Value = key.Key;
  177. if (((int)_cmd.ExecuteScalar()) < 1)
  178. {
  179. // not exists , record the key
  180. _cmd.Parameters.Clear();
  181. _cmd.CommandText = "insert into WebQueryKeyCollection (QueryKey) values (@key)";
  182. _cmd.Parameters.Add("@key", System.Data.SqlDbType.NVarChar).Value = key.Key;
  183. _cmd.ExecuteNonQuery();
  184.  
  185. // take last key id
  186. _cmd.Parameters.Clear();
  187. _cmd.CommandText = "select top 1 Id from WebQueryKeyCollection order by Id DESC";
  188. q.KeyID = (int)_cmd.ExecuteScalar();
  189. }
  190. else
  191. {
  192. // take key’s id
  193. _cmd.Parameters.Clear();
  194. _cmd.CommandText = "select Id from WebQueryKeyCollection where QueryKey=@key";
  195. _cmd.Parameters.Add("@key", System.Data.SqlDbType.NVarChar).Value = key;
  196. q.KeyID = (int)_cmd.ExecuteScalar();
  197. }
  198.  
  199. // take Value ID
  200. _cmd.Parameters.Clear();
  201. _cmd.CommandText = "select Count(Id) from WebQueryValueCollection where QueryValue=@value";
  202. _cmd.Parameters.Add("@value", System.Data.SqlDbType.NVarChar).Value = key.Value;
  203. if (((int)_cmd.ExecuteScalar()) < 1)
  204. {
  205. // not exists , record the key
  206. _cmd.Parameters.Clear();
  207. _cmd.CommandText = "insert into WebQueryValueCollection (QueryValue) values (@value)";
  208. _cmd.Parameters.Add("@value", System.Data.SqlDbType.NVarChar).Value = key.Value;
  209. _cmd.ExecuteNonQuery();
  210.  
  211. // take last key id
  212. _cmd.Parameters.Clear();
  213. _cmd.CommandText = "select top 1 Id from WebQueryValueCollection order by Id DESC";
  214. q.ValueID = (int)_cmd.ExecuteScalar();
  215. }
  216. else
  217. {
  218. // take value’s id
  219. _cmd.Parameters.Clear();
  220. _cmd.CommandText = "select Id from WebQueryValueCollection where QueryValue=@value";
  221. _cmd.Parameters.Add("@value", System.Data.SqlDbType.NVarChar).Value = key;
  222. q.ValueID = (int)_cmd.ExecuteScalar();
  223. }
  224. #endregion
  225.  
  226. #region Insert QueryID,ValueID,ErrorID
  227. _cmd.Parameters.Clear();
  228. _cmd.CommandText = "insert into WebSiteQuerys (QueryStringKey,QueryStringValue,ErrorID) values
  229.  
  230. (@p1,@p2,@p3)";
  231. _cmd.Parameters.Add("@p1", System.Data.SqlDbType.Int).Value = q.KeyID;
  232. _cmd.Parameters.Add("@p2", System.Data.SqlDbType.Int).Value = q.ValueID;
  233. _cmd.Parameters.Add("@p3", System.Data.SqlDbType.Int).Value = e.ErrorID;
  234. _cmd.ExecuteNonQuery();
  235. #endregion
  236. }
  237. _cmd.Parameters.Clear();
  238. }
  239. #endregion
  240.  
  241. // Step 7 => record ip address
  242. #region MyRegion
  243. _cmd.CommandText = "select Count(Id) from WebErrorIPList where IP=@ip";
  244. _cmd.Parameters.Add("@ip", System.Data.SqlDbType.NVarChar).Value = this._webAddrIP;
  245. int ipCount = (int)_cmd.ExecuteScalar();
  246.  
  247. int iPID = 0;
  248. if (ipCount < 1)
  249. {
  250. // ip not exists , record it
  251. _cmd.Parameters.Clear();
  252. _cmd.CommandText = "insert into WebErrorIPList (IP) values (@ip)";
  253. _cmd.Parameters.Add("@ip", System.Data.SqlDbType.NVarChar).Value = this._webAddrIP;
  254. _cmd.ExecuteNonQuery();
  255.  
  256. // take last ip id
  257. _cmd.Parameters.Clear();
  258. _cmd.CommandText = "select Id from WebErrorIPList order by Id DESC";
  259. iPID = (int)_cmd.ExecuteScalar();
  260. }
  261. else
  262. {
  263. // exitst that ip , take its
  264. _cmd.Parameters.Clear();
  265. _cmd.CommandText = "select Id from WebErrorIPList where IP=@ip";
  266. _cmd.Parameters.Add("@ip", System.Data.SqlDbType.NVarChar).Value = this._webAddrIP;
  267. iPID = (int)_cmd.ExecuteScalar();
  268. }
  269.  
  270. _cmd.Parameters.Clear();
  271. _cmd.CommandText = "insert into WebErrorIP (IP,ErrorID) values (@ip,@err)";
  272. _cmd.Parameters.Add("@ip", System.Data.SqlDbType.Int).Value = iPID;
  273. _cmd.Parameters.Add("@err", System.Data.SqlDbType.Int).Value = e.ErrorID;
  274. _cmd.ExecuteNonQuery();
  275. #endregion
  276.  
  277. // Step 8 => record reason
  278. #region MyRegion
  279. _cmd.Parameters.Clear();
  280. _cmd.CommandText = "select Count(Id) from ErrorReasons where Reason = @r";
  281. _cmd.Parameters.Add("@r", System.Data.SqlDbType.NVarChar).Value = _reason;
  282. int reasonCount = (int)_cmd.ExecuteScalar();
  283. if (reasonCount < 1)
  284. {
  285. // reason not exists , record it
  286. _cmd.Parameters.Clear();
  287. _cmd.CommandText = "insert into ErrorReasons (Reason) values (@r)";
  288. _cmd.Parameters.Add("@r", System.Data.SqlDbType.NVarChar).Value = _reason;
  289. _cmd.ExecuteNonQuery();
  290.  
  291. _cmd.Parameters.Clear();
  292. _cmd.CommandText = "select top 1 Id from ErrorReasons order by Id DESC";
  293. e.ErrorReasonID = (int)_cmd.ExecuteScalar();
  294. }
  295. else
  296. {
  297. _cmd.Parameters.Clear();
  298. _cmd.CommandText = "select Id from ErrorReasons where Reason = @r";
  299. _cmd.Parameters.Add("@r", System.Data.SqlDbType.NVarChar).Value = _reason;
  300. e.ErrorReasonID = (int)_cmd.ExecuteScalar();
  301. }
  302. #endregion
  303.  
  304. // RECORD ERROR
  305. #region MyRegion
  306. _cmd.Parameters.Clear();
  307. _cmd.CommandText = "insert into WebErrors (ErrorID,ErrorWebID,ErrorDate,ErrorURL,ErrorReasonID) values
  308.  
  309. (@p1,@p2,@p3,@p4,@p5)";
  310. _cmd.Parameters.Add("@p1", System.Data.SqlDbType.Int).Value = e.ErrorID;
  311. _cmd.Parameters.Add("@p2", System.Data.SqlDbType.Int).Value = e.ErrorWebID;
  312. _cmd.Parameters.Add("@p3", System.Data.SqlDbType.DateTime).Value = e.ErrorDate;
  313. _cmd.Parameters.Add("@p4", System.Data.SqlDbType.Int).Value = e.ErrorUrlID;
  314. _cmd.Parameters.Add("@p5", System.Data.SqlDbType.Int).Value = e.ErrorReasonID;
  315. _cmd.ExecuteNonQuery();
  316. #endregion
  317.  
  318. _conn.Close();
  319. _cmd.Parameters.Clear();
  320. _conn = null;
  321. _cmd = null;
  322. }
  323. }
  324.  
  325. public class Error
  326. {
  327. public int ErrorID { get; set; }
  328. public DateTime ErrorDate { get; set; }
  329. public int ErrorWebID { get; set; }
  330. public int ErrorUrlID { get; set; }
  331. public int ErrorReasonID { get; set; }
  332. }
  333. public class QueryStringValue
  334. {
  335. public string Key { get; set; }
  336. public string Value { get; set; }
  337. }
  338. public class QueryString
  339. {
  340. public int KeyID { get; set; }
  341. public int ValueID { get; set; }
  342. }
  343. }

yukarıdaki kodlardan bir ClassLibrary Project ile ürün olarak DLL yaratıyoruz.CustomException.dll’imizi web sayfalarimiza referans etmeliyiz.

Bir WebSite açiyoruz ve olusturduğumuz kütüphaneyi Add Reference diyip , oradan da Browse dll in yolunu bularak sayfamıza ekliyoruz.işlem sonunda gelelim web sitemiz içerisinde ne olacak , amac sadece olusan hataları kayıt etmek olduğu için cok basit 2 durumu gündeme aliyorum , web site içerisinde 2 tane sayfa bulunmakta , => Default.aspx ve Default2.aspx , bu sayfalardan sadece Default.aspx sayfasının tasarimi var , onu paylaşalim ve hemen arkasından kodları …

Default.aspx Design

Default.aspx Design

Default.aspx.cs :

  1. using System;
  2. // kendi Kütüphanemiz…
  3. using CustomException;
  4.  
  5. public partial class _Default : System.Web.UI.Page
  6. {
  7. protected void Page_Load(object sender, EventArgs e)
  8. {
  9.  
  10. }
  11. protected void lnkKaresiniAl_Click(object sender, EventArgs e)
  12. {
  13. try
  14. {
  15. // TextBox kontrolüne metinsel formatta değegerler girelim
  16. // Parse işlemi patlasin
  17. // örn : 132a => int bir değere çevirilemez durumu.
  18. int sayi = int.Parse(TextBox1.Text);
  19. lblBilgi.Text = (sayi * sayi).ToString();
  20. }
  21. catch (Exception ex)
  22. {
  23. CustomEx cx = new CustomEx(ex.Message,ex.TargetSite.Name,Request.ServerVariables["LOCAL_ADDR"],Request.ServerVariables["REMOTE_ADDR"],Request.Url.Segments,Request.QueryString,Request.ServerVariables["SERVER_NAME"]);
  24. cx.RegError();
  25. Response.Write(ex.Message);
  26. }
  27. }
  28. }

Default2.aspx.cs

  1. using System;
  2. using CustomException;
  3.  
  4. public partial class Default2 : System.Web.UI.Page
  5. {
  6. protected void Page_Load(object sender, EventArgs e)
  7. {
  8. try
  9. {
  10. // Bu sayfaya talebi => Default2.aspx?Id=5555555555555555555555555555
  11. // biçiminde yapalim ve taşma hatasi meydana getirelim
  12. int sayi = int.Parse(Request.QueryString["Id"]);
  13. }
  14. catch (Exception ex)
  15. {
  16. CustomEx cx = new CustomEx(ex.Message, ex.TargetSite.Name, Request.ServerVariables["LOCAL_ADDR"], Request.ServerVariables["REMOTE_ADDR"], Request.Url.Segments, Request.QueryString, Request.ServerVariables["SERVER_NAME"]);
  17. cx.RegError();
  18. Response.Write(ex.Message);
  19. }
  20. }
  21. }

Default.aspx de hata yaratalim…

Exception On Web

Exception On Web

Hata Kayıtı WebErrors tablomuza düşüyor,saat bilgisinden yakalayabiliriz.

Web Error Records

Web Error Records

Error Messages

Error Messages

Testler sırasında daha önceden karşılaşılan bir hata olduğu için veri yinelemesi olmadi , var olan kayıta ait kayit ID bilgisi girdi yapilir.

Default2.aspx Error

Default2.aspx Error

QueryString’ler çalışırken , meydana gelebilecek hatalarda sorgu katarlarini yakaliyoruz… hem key hem value değerleri …

Default2's Query & Value And Error Record

Default2's Query & Value And Error Record

Proje içerisinde diğer tablolarda kayıtlar oluşturulmuştur fakat onları daha fazla uzamasın diye paylaşmiyorum,bu bilgiler bir projenin kontrolü için en az Trace işlemi kadar önemlidir,tabiki örneğimizin eksiklikleri vardir,ben kısa zamanda bir çözüm bulmak adına böyle bir konu üzerinde aklıma gelmişken yazayım dedim , sizler daha da geliştirebilirsiniz,hepimize kolay gelsin … (: hevfan (:

ASP.NET VirtualPathProvider Kullanimi

Can sıkıntısı saatlerine tekrar merhaba,ayağımız alışsın kampamyasına katılmayanlariniz yoktur , o sebeple güzel bir konu ile tekrar karşınızdayız , örnek üzerinden yürüttüğümüz örnek virtualPathProvider örneği olarak değerlendirilebilir,web sitelerinde görebileceğimiz ve proje gereği kullanilmasi gereken , fiziksel olarak dosyalarin saklanma yerinin bir veritabani oldugu durumlarda kullanılmaktadır.bu konuyu rewriteurl ile karıştırmamamız gerekir,o konuda en basitinden IIS üzerinde ayarlar yapilmasi gerekirken , burada sadece bir veritabani ve bir özel sinif yazimi söz konusu olmustur.

bir MSSQL Veritabani hazırlayarak işlemlerimize başlayalim :

create database VirtualPathDB

use VirtualPathDB

create table tblSanalSayfalar
(
DosyaID    int identity(1,1),
DosyaAdi nvarchar(200),
DosyaIcerik nvarchar(max)
)

create table tblOyuncular
(
OyuncuID int identity(1,1),
OyuncuAdi nvarchar(10),
OyuncuTakimi nvarchar(20)
)

hemen arkasindan , bu oyuncu tablosuna veri girişi yapabilirsiniz.Uygulamanin bu kısmını geçtikten sonra , sıra artik tblSanalSayfalar tablosuna veri girişi yapmaya geldi,ve bu şekilde fiziksel bir dosya kullanmak yerine , fiziksel dosyanın kodlarini veritabani üzerinde bulunan bir tabloda tutarak , sanal yol yaratma yoluna girmiş oluyoruz , nasipse çıkarız (:

tblSanalSayfalar tablosuna bir kayit ekliyoruz,bu kayitin görünümü aşağıdaki gibidir , ve DosyaIcerik kolonunda tutulan verilerde daha öncesinden yazdığım bir aspx dosyasının tüm içeriğidir , biraz üzerinde oynama yapmamiz gerekicektir , çünki veritabanindan çekilecek bir kod içeriği için , .aspx ile biten bir dosyanın Page direktifinde bu sayfanın hangi codefile ile çalıstığı bilgisi bulunmaktadir,biz tüm işlemleri gerek tasarim gerek C# olarak , InlineCoding yontemi ile sayfa içerisinde yapmamiz gerekir,Page direktifinden CodeFile ve Inherits bölümlerini siliyoruz,ve kolona kaydedilecek olan kodlar aşağıda görüldüğü gibi olmaktadir.

<%@ Page Language=”C#”%>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml”>
<head runat=”server”>
<title>Untitled Page</title>
<script runat=”server”>
protected void ButonTiklandi(object obj, EventArgs e)
{
System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection();
cn.ConnectionString = “data source=localhost;initial catalog=VirtualPathDB;integrated security=true”;
System.Data.SqlClient.SqlCommand cmd = cn.CreateCommand();
cmd.CommandText = “select * from tblOyuncular”;
System.Data.SqlClient.SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(cmd);

System.Data.DataTable dt = new System.Data.DataTable();
da.Fill(dt);

oyuncuGrid.DataSource = dt;
oyuncuGrid.DataBind();
}
</script>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>

Veritabanindan Gelen Verilerle Olusan Sayfa<br />
<asp:LinkButton ID=”lnkVeriGetir” runat=”server” OnClick=”ButonTiklandi”>Veri Getir</asp:LinkButton>
<br />
<br />
<asp:GridView ID=”oyuncuGrid” runat=”server” BackColor=”LightGoldenrodYellow”
BorderColor=”Tan” BorderWidth=”1px” CellPadding=”2″ ForeColor=”Black”
GridLines=”None”>
<FooterStyle BackColor=”Tan” />
<PagerStyle BackColor=”PaleGoldenrod” ForeColor=”DarkSlateBlue”
HorizontalAlign=”Center” />
<SelectedRowStyle BackColor=”DarkSlateBlue” ForeColor=”GhostWhite” />
<HeaderStyle BackColor=”Tan” Font-Bold=”True” />
<AlternatingRowStyle BackColor=”PaleGoldenrod” />
</asp:GridView>

</div>
</form>
</body>
</html>

yukaridaki kodlari kolona kaydederken , bosluklari kopyalarken dikkat etmenizi öneririm

VirtualPathDB

Bu adimi da geçtikten sonra , gelelim artik VirtualPathProvider kullanımına , bunun için App_Code klasörü içerisinde bir sınıf açiyoruz ve kodlarimiz şu şekildedir.

  1. using System.Data;
  2. using System.Web.Hosting;
  3. using System.IO;
  4. using System.Data.SqlClient;
  5.  
  6. public class CustomVirtualPathProvider : VirtualPathProvider
  7. {
  8. public static void AppInitialize()
  9. {
  10. CustomVirtualPathProvider c = new CustomVirtualPathProvider();
  11. HostingEnvironment.RegisterVirtualPathProvider(c);
  12. }
  13.  
  14. public string VeritabanindanDosyayiGetir(string _sanalSayfa)
  15. {
  16. string _sanal = string.Empty;
  17. string _dosya = _sanalSayfa.Substring(_sanalSayfa.IndexOf(‘/’,1) + 1);
  18.  
  19. SqlConnection cn = new SqlConnection();
  20. cn.ConnectionString = "data source=localhost;initial catalog=VirtualPathDB;integrated security=true";
  21. SqlCommand cmd = cn.CreateCommand();
  22. cmd.CommandText = "select DosyaIcerik from tblSanalSayfalar where DosyaAdi=@ad";
  23. cmd.Parameters.Add("@ad", SqlDbType.NVarChar).Value = _dosya;
  24.  
  25. cn.Open();
  26. object obj = cmd.ExecuteScalar();
  27. if (obj != null)
  28. _sanal = obj.ToString();
  29.  
  30. return _sanal;
  31. }
  32.  
  33. public override VirtualFile GetFile(string virtualPath)
  34. {
  35. string icerik = this.VeritabanindanDosyayiGetir(virtualPath);
  36. if (icerik == string.Empty)
  37. return Previous.GetFile(virtualPath);
  38. else
  39. return new CustomVirtualFile(virtualPath, icerik);
  40. }
  41.  
  42. public override bool FileExists(string virtualPath)
  43. {
  44. string icerik = this.VeritabanindanDosyayiGetir(virtualPath);
  45. if (icerik == string.Empty)
  46. return Previous.FileExists(virtualPath);
  47. else
  48. return true;
  49. }
  50. }
  51.  
  52. public class CustomVirtualFile : VirtualFile
  53. {
  54. string _DosyaIcerik;
  55.  
  56. public CustomVirtualFile(string _sanalSayfa,string _icerik):base(_sanalSayfa)
  57. {
  58. this._DosyaIcerik = _icerik;
  59. }
  60.  
  61. public override System.IO.Stream Open()
  62. {
  63. MemoryStream ms = new MemoryStream();
  64. StreamWriter sw = new StreamWriter(ms, System.Text.Encoding.Unicode);
  65.  
  66. sw.Write(_DosyaIcerik);
  67. sw.Flush();
  68. ms.Seek(0, SeekOrigin.Begin);
  69. return ms;
  70. }
  71. }

Default.aspx’imiz

Default.aspx

ve kodlari :

<%@ Page Language=”C#” AutoEventWireup=”true”  CodeFile=”Default.aspx.cs” Inherits=”_Default” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml”>
<head runat=”server”>
<title>AnaSayfa</title>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>

Fiziksel Sayfamız : Default.aspx<br />
<br />
Sanal ( Virtual ) Sayfalar<br />
<a href=”SanalOyuncuSayfasi.aspx”>Oyuncu</a></div>
</form>
</body>
</html>

SanalOyuncuSayfasi.aspx’e tikladiğimizda,gelen sayfamiz :

Virtual Page

Virtual Page

ASP.NET Tek DataGrid’de 2 DataTable

Sayfa tasarimi :

Sayfa Tasarimi

Default.aspx.cs kodlarimiz

  1. using System;
  2. using System.Data;
  3. using System.Data.SqlClient;
  4.  
  5. public partial class _Default : System.Web.UI.Page
  6. {
  7. protected void Page_Load(object sender, EventArgs e)
  8. {
  9. this.TekGrid();
  10. }
  11.  
  12. void TekGrid()
  13. {
  14. string _connectionString = "data source=localhost;initial catalog=AdventureWorks;integrated security=true";
  15.  
  16. SqlConnection _cn1 = new SqlConnection(_connectionString);
  17. SqlConnection _cn2 = new SqlConnection(_connectionString);
  18.  
  19. SqlDataAdapter _adapter1 = new SqlDataAdapter("select ProductID,Name,ListPrice,SafetyStockLevel,Color,ProductSubcategoryID from Production.Product", _cn1);
  20. SqlDataAdapter _adapter2 = new SqlDataAdapter("select ProductSubcategoryID,Name from Production.ProductSubcategory", _cn2);
  21.  
  22. DataTable _dt1 = new DataTable();
  23. DataColumn[] _cl1 = new DataColumn[]
  24. {
  25. new DataColumn("ID",typeof(int))
  26. {
  27. AutoIncrement = true,
  28. Unique = true,
  29. AutoIncrementSeed = 1,
  30. AutoIncrementStep = 1
  31. },
  32. new DataColumn("Name",typeof(string)),
  33. new DataColumn("SurName",typeof(string))
  34. };
  35.  
  36. _dt1.Columns.AddRange(_cl1);
  37.  
  38. DataTable _dt2 = new DataTable();
  39. DataColumn[] _cl2 = new DataColumn[]
  40. {
  41. new DataColumn("ID",typeof(int))
  42. {
  43. AutoIncrement = true,
  44. Unique = true,
  45. AutoIncrementSeed = 1,
  46. AutoIncrementStep = 1
  47. },
  48. new DataColumn("Address",typeof(string)),
  49. new DataColumn("City",typeof(string))
  50. };
  51.  
  52. _dt2.Columns.AddRange(_cl2);
  53.  
  54. string[] _names = new string[]
  55. {
  56. "kenan","myfan","yourfan","irfan","coder","şimdi uzaklardasin"
  57. };
  58.  
  59. string[] _surNames = new string[]
  60. {
  61. "kalfa","dedikodu","liar","pinokyo"
  62. };
  63.  
  64. string[] _adresses = new string[]
  65. {
  66. "moda","yenidogan","tandogan","kordon","maslak"
  67. };
  68.  
  69. string[] _cities = new string[]
  70. {
  71. "istanbul","ankara","izmir"
  72. };
  73.  
  74. Random rnd = new Random();
  75. for (int i = 0; i &lt; 10; i++)
  76. {
  77. DataRow _row = _dt1.NewRow();
  78.  
  79. _row["Name"] = _names[rnd.Next(0, _names.Length)];
  80. _row["SurName"] = _surNames[rnd.Next(0, _surNames.Length)];
  81. _dt1.Rows.Add(_row);
  82. System.Threading.Thread.Sleep(10);
  83. }
  84.  
  85. for (int i = 0; i &lt; 10; i++)
  86. {
  87. DataRow _row = _dt2.NewRow();
  88.  
  89. _row["Address"] = _adresses[rnd.Next(0, _adresses.Length)];
  90. _row["City"] = _cities[rnd.Next(0, _cities.Length)];
  91. _dt2.Rows.Add(_row);
  92. System.Threading.Thread.Sleep(10);
  93. }
  94.  
  95. _dt1.PrimaryKey = new DataColumn[] { _dt1.Columns[0] };
  96. _dt2.PrimaryKey = new DataColumn[] { _dt2.Columns[0] };
  97.  
  98. _dt1.Merge(_dt2, false, MissingSchemaAction.AddWithKey);
  99.  
  100. myGrid.DataSource = _dt1;
  101. myGrid.DataBind();
  102. }
  103. }

Çıktı :

One Grid,Multi DataTable

ASP.NET Async IP Trace Tutorial

Can sıkıntısına , ilginç şeyler çıkmaya görsün , oturup yazdırıyor kendini (: , sağlik olsun.. Gelelim bu yazımızın girişine , ve neler yapacağimiza , IP , malumunuz tüm internete bağlı olan bilgisayarin ortak özelliklerinden bir tanesi ve herkes internet sağlayicisi ve çeşitli vasitalar ile dünyanın dört bir yanındaki diğer bilgisayarlara ( user , server ) bağlanabiliyor,bu işlem için her bilgisayar kendi IP’si ile yollar izleyerek istenilen hedefe ulasmaktadir,bu ulaşim boyunca birden cok durağı geçer.. Bizde bu yazımızda örnek bir IP adresi bilgisi üzerinden , o adrese uygulamamizin ulaşırken geçecek yollari listeleteceğiz , bilgisayarımızda bulunan tracert.exe ile bu işlem gerçekleştirilebilir fakat , network üzerinde yürüyen işlemler olduğundan güclü bağlantılar gerekmektedir , bu tür bir bağlantıyı da nedense güzel Türkiye’mde değilde ancak yunanistan teknik üniversitesinde bulabildim bu işlem için , sağolsunlar onların gençlerine açmişlar bu imkanlari …

Ilk önce bir Web Site açalim , ve Default.aspx dosyamızın tasarimini gördüğümüz gibi yapalim

Default.aspx Design

Default.aspx Design

Default.aspx dosyasının CodeFile’ında bulunan kodlarimizi paylaşalim,

  1. using System;
  2.  
  3. public partial class _Default : System.Web.UI.Page
  4. {
  5. protected void Page_Load(object sender, EventArgs e)
  6. {
  7. this.Title = "Trace Islemi";
  8. lnkTraceButton.PostBackUrl = "TraceResult.aspx";
  9. }
  10. }

Sıra geldi şimdi bizim için , TraceResult.aspx adini verdiğimiz , sonucları göreceğimiz ve işlemleri yaptiracağimiz olan asp.net sayfamıza , tasarimi aşağıda görüldüğü gibidir…

TraceResult.aspx design

TraceResult.aspx design

Bu sayfanın tasarimini tamamladiktan sonra, .cs dosyasının kodlarini paylaşalim

  1. using System;
  2. using System.Web.UI;
  3. using System.Web.UI.WebControls;
  4.  
  5. public partial class TraceResult : System.Web.UI.Page
  6. {
  7. Yonetim y;
  8. protected void Page_Load(object sender, EventArgs e)
  9. {
  10. this.Title = "Trace Islemi Sonuclari";
  11. if (PreviousPage != null)
  12. {
  13. TextBox txt = (TextBox)PreviousPage.FindControl("txtIPAdres");
  14. y = new Yonetim(txt.Text, this.plcKontrolHolder);
  15. PageAsyncTask task = new PageAsyncTask(y.Baslat, y.IslemBitir, null, null);
  16. Page.RegisterAsyncTask(task);
  17. }
  18. }
  19. protected void lnkTurnBack_Click(object sender, EventArgs e)
  20. {
  21. Response.Redirect("Default.aspx");
  22. }
  23. }

Islemleri yaptirdiğimiz ve nesne yönelimli mimari gereği , kullandığımı Yonetim sınıfımızın kodları :

  1. using System;
  2. using System.Web.UI.WebControls;
  3. using System.Collections.Generic;
  4. using System.Net;
  5. using System.IO;
  6.  
  7. public class Yonetim
  8. {
  9. public List&lt;string&gt; _IPYollari { get;set;}
  10. public string _IP {get;set;}
  11. Action _action;
  12. PlaceHolder _holder;
  13.  
  14. public Yonetim (string ip,PlaceHolder holder)
  15. {
  16. _IPYollari = new List&lt;string&gt;();
  17. this._IP = ip;
  18. _action = new Action(Islem);
  19. _holder = holder;
  20. }
  21.  
  22. public IAsyncResult Baslat(object sender, EventArgs e, AsyncCallback callBack, object state)
  23. {
  24. return _action.BeginInvoke(callBack, state);
  25. }
  26. void Islem()
  27. {
  28. _IPYollari.Clear();
  29. string _pageContent = string.Empty;
  30. try
  31. {
  32. WebRequest _request = WebRequest.Create(string.Format("http://www.ntua.gr/cgi-bin/rtracert?name={0}", this._IP));
  33. WebResponse _response = _request.GetResponse();
  34.  
  35. Stream _stream = _response.GetResponseStream();
  36. StreamReader _reader = new StreamReader(_stream);
  37.  
  38. _pageContent = _reader.ReadToEnd();
  39. if (_pageContent.Length &lt; 1)
  40. return;
  41. }
  42. catch
  43. {
  44. return;
  45. }
  46. string icMetin = string.Empty;
  47. string metin = string.Empty;
  48.  
  49. for (int i = 0; i &lt; _pageContent.Length - 4; i++)
  50. {
  51. metin += _pageContent[i]; // &lt;
  52. metin += _pageContent[i + 1]; // p
  53. metin += _pageContent[i + 2]; // r
  54. metin += _pageContent[i + 3]; // e
  55. metin += _pageContent[i + 4]; // &gt;
  56.  
  57. if (metin == "&lt;pre&gt;")
  58. {
  59. for (int k = i + 5; k &lt; _pageContent.Length; k++)
  60. {
  61. if ((_pageContent[k].ToString() + _pageContent[k + 1].ToString() + _pageContent[k + 2].ToString() + _pageContent[k + 3].ToString() + _pageContent[k + 4].ToString() + _pageContent[k + 5].ToString()) == "&lt;/pre&gt;")
  62. {
  63. break;
  64. }
  65. else
  66. icMetin += _pageContent[k];
  67. }
  68. // veriler alindi
  69. break;
  70. }
  71. else
  72. {
  73. metin = string.Empty;
  74. }
  75. }
  76.  
  77. for (int i = 0; i &lt; icMetin.Length; i++)
  78. {
  79. if (char.IsNumber(icMetin[i]) &amp;&amp; (icMetin[i + 1].ToString() + icMetin[i + 2].ToString()) == "  ")
  80. {
  81. string adres = string.Empty;
  82. for (int k = i + 3; ; k++)
  83. {
  84. if (icMetin[k].ToString() != " ")
  85. adres += icMetin[k].ToString();
  86. else
  87. break;
  88. }
  89. _IPYollari.Add(adres);
  90. }
  91. }
  92.  
  93. if (this._IPYollari.Count &gt; 0)
  94. {
  95. ListBox lst = new ListBox();
  96. lst.Height = 500;
  97. foreach (string item in this._IPYollari)
  98. lst.Items.Add(new ListItem(item));
  99.  
  100. this._holder.Controls.Add(lst);
  101. }
  102. else
  103. {
  104. Label lbl = new Label();
  105. lbl.Text = "Sonuc Yok";
  106. this._holder.Controls.Add(lbl);
  107. }
  108. }
  109. public void IslemBitir(IAsyncResult ra)
  110. {
  111. _action.EndInvoke(ra);
  112. }
  113. }

tüm bu hazırlıkların sonunda , Default.aspx sayfamızı ziyaret edelim ve bu sayfadan örnek bir IP değerini , Trace işlemine koyalim :

IP Trace Starting

IP Trace Starting

Islem Sonuclari

Trace Results...

Trace Results...