Daha önce burada yapmış olduğum Anket uygulaması nasıl olurda pasta grafiği ile gösterilir dedim, böyleymiş.
Bitmap myB = new Bitmap(500, 400);
Graphics g = Graphics.FromImage(myB);
g.Clear(Color.White);
Rectangle hedRec = new Rectangle(0, 0, 500, 75);
Rectangle hedRecShadow = new Rectangle(1, 1, 500, 75);
Rectangle pieRec = new Rectangle(5, 100, 200, 200);
StringFormat strF = new StringFormat();
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
strF.Alignment = StringAlignment.Center;
XPathDocument pDoc = new XPathDocument(Server.MapPath("./App_Data/anket.xml"));
XPathNavigator nav = pDoc.CreateNavigator();
int toplamCevap = Convert.ToInt32(nav.Evaluate("count(/Anket/cevap)"));
int toplamOy = Convert.ToInt32(nav.Evaluate("sum(/Anket/cevap)"));
float angel = 0, sweep = 0, oran = 0;
string header = nav.SelectSingleNode("Anket").GetAttribute("ad", "");
g.DrawString(header, new Font("arial", 20, FontStyle.Bold), Brushes.Gray, hedRecShadow, strF);
g.DrawString(header, new Font("arial", 20, FontStyle.Bold), Brushes.Goldenrod, hedRec, strF);
g.DrawLine(new Pen(Color.Black), 5, 75, 495, 75);
XPathNodeIterator nodes = nav.Select("Anket/cevap");
int top = 125;
while(nodes.MoveNext())
{
sweep = 360 * Convert.ToSingle(nodes.Current.InnerXml) / toplamOy;
g.FillPie(new SolidBrush(Color.FromName(nodes.Current.GetAttribute("renk", ""))), pieRec, angel, sweep);
oran = 100 * Convert.ToSingle(nodes.Current.InnerXml) / toplamOy;
g.DrawString("% " + oran.ToString("n"), new Font("arial", 9, FontStyle.Regular), Brushes.Black, 250, top);
g.FillRectangle(new SolidBrush(Color.FromName(nodes.Current.GetAttribute("renk", ""))), 320, (top - 6), 20, 20);
g.DrawString(nodes.Current.GetAttribute("text", ""), new Font("arial", 9, FontStyle.Regular), Brushes.Black, 355, top);
angel += sweep;
top += 35;
}
MemoryStream mem = new MemoryStream();
myB.Save(mem, System.Drawing.Imaging.ImageFormat.Gif);
Response.BinaryWrite(mem.ToArray());
sonuç:

Generic class oluştururken birden fazla tip parametesi ve herbiri için kısıtlama verilecekse anahtar kelime enter olacaktır.
public class point<T, U> //----- enter
where T : struct //----- enter
where U : struct
{
T x, y, z;
U t;
......
Bir uygulama düşünün ki veriler xml dosyasında sunum ise web formunda olsun.
İşte tam aradığımız kontrol;
<
asp:Xml ID="Xml1" runat="server" DocumentSource="~/App_Data/anket.xml" TransformSource="~/App_Data/Anket.xslt"></asp:Xml>Verileri Xml dosyasında saklamının avantajlarından birisi de Xslt ile web uygulamalarına kolayca adapte edilebilmesidir. Örnek Xml verisi için Xslt kodu;
<?xml version="1.0" encoding="utf-8"?>ve sonuç;

Özel bir eğitim için 2 hafta süresince C++ dili ile ilgili araştırmalar yapma fırsatım oldu. Aynı uygulamayı 3 farklı dil versiyonunda yazdım. Sonra şu soruyu sordum kendime, C# bilmek C++ öğrenmek için bir avantaj olabilir mi yada tam tersi. Sanırım cevap kodlarda gizli
//C#
int[] sayilar = new int[6];
Random rnd = new Random();
int index = 0;
while (index < 6)
{
int sayi = rnd.Next(1, 50);
if (Array.IndexOf(sayilar, sayi) == -1)
sayilar[index++] = sayi;
}
Array.Sort(sayilar);
//CLR C++
array<int>^ sayilar = gcnew array<int>(6);
Random^ rnd = gcnew Random();
int index = 0;
while(index < 6)
{
int sayi = rnd->Next(1,50);
if(Array::IndexOf(sayilar,sayi) == -1)
sayilar[index++] = sayi;
}
Array::Sort(sayilar);
//Native C++
#include "stdafx.h"
#include "iostream"
#include "Shlwapi.h"
#include "windows.h"
using namespace std;
int myRandom();
int IndexOf(int dizi[],int eleman);
void Sort(int dizi[]);
int _tmain(int argc, _TCHAR* argv[])
{
int sayilar[6];
int index = 0;
while(index < 6)
{
int sayi = myRandom();
if(IndexOf(sayilar,sayi) == -1)
{
sayilar[index] = sayi;
index++;
}
}
Sort(sayilar);
for(int i = 0;i<6;i++)
cout << sayilar[i] << endl;
return 0;
}
void Sort(int dizi[])
{
for(int i = 0;i<sizeof dizi;i++)
{
int min = dizi[i];
for(int j = i +1;j<sizeof dizi;j++)
{
if(dizi[j] < min)
{
int temp = min;
min = dizi[j];
dizi[j] = temp;
}
dizi[i] = min;
}
}
}
int IndexOf(int dizi[],int eleman)
{
for(int i = 0;i<sizeof dizi;i++)
{
if(dizi[i] == eleman)
return i;
}
return -1;
}
int myRandom()
{
Sleep(100);
DWORD dwTick = GetTickCount();
srand(dwTick);
int sayi;
do
{
sayi = rand() % 50;
}
while(sayi == 0);
return sayi;
}
Bazen Asp.Net sayfalarımızın client tarafında durum gereği farklı davranmasını isteyebiliriz. Tabiki javascript kodlarını devreye sokarak.
.NET Framework 2.0 versiyonu ile bunu yapmanın yolu ClientScriptManager Class ının RegisterStartupScript metodunu kullanmak olacaktır.
Bilindiği gibi RegisterStartupScript metodu 1.1 versiyonuda da bulunmaktaydı. Birçok metod gibi 2.0 ile bunun da kullanımı biraz değişmiş :)
Uygulamamızda;
client tarafında
window.open( [sURL] [, sName] [, sFeatures] [, bReplace]) metodunu
kod tarafında ise
public void RegisterClientScriptBlock ( Type type, string key, string script ) metodunu kullanacağız.
Şimdi ise Logon Button' nun Click Olayına ilgili kodu yazalım,
if (logon())
{
ClientScriptManager csm = Page.ClientScript;
StringBuilder sb = new StringBuilder();
sb.Append("<script language=\"javascript\">");
sb.Append("window.onload = function()");
sb.Append("{");
sb.Append("window.open(\"loading.aspx\",\"load\",\"");
sb.Append("height=\" + (window.screen.availHeight - 30) + \",");
sb.Append("width=\" + (window.screen.availwidth - 10) + \",");
sb.Append("top=0, left=0, menubar=0, location=0, resizable=1, status=0\");");
sb.Append("if (window.name != \"load\")");
sb.Append("{");
sb.Append("this.focus();");
sb.Append("top.window.opener = top;");
sb.Append("top.window.open('','_parent','');");
sb.Append("top.window.close();");
sb.Append("}");
sb.Append("}");
sb.Append("</script>");
csm.RegisterClientScriptBlock(this.GetType(), string.Empty, sb.ToString());
}
else
{
//Giriş Başarısız
}
Eğer GDI+ kullanarak bir metni tam olarak hizalamak isterseniz,
Graphics g = panel1.CreateGraphics();
g.FillRectangle(new LinearGradientBrush(panel1.ClientRectangle, Color.WhiteSmoke, Color.SkyBlue, 90), panel1.ClientRectangle);
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
g.DrawString("center", new Font("verdana", 12, FontStyle.Bold), Brushes.Maroon, panel1.ClientRectangle, sf);

Bir projede Login kontrollerinden PasswordRecovery kullanıyorum. E-mail içeriğindeki Türkçe karakterler problemli gözüküyor. Önce bu şekilde denedim.
using System.Text;
....
protected void PasswordRecovery1_SendingMail(object sender, MailMessageEventArgs e)
{
e.Message.SubjectEncoding = Encoding.GetEncoding("iso-8859-9");
e.Message.BodyEncoding = Encoding.GetEncoding("iso-8859-9");
}
olmadı, bende işi biraz uzattım ama oldu :) - daha pratik birşey bulursam alta eklerim -
using System.Text;
using System.IO;
....
protected void PasswordRecovery1_SendingMail(object sender, MailMessageEventArgs e)
{
e.Message.SubjectEncoding = Encoding.GetEncoding("iso-8859-9");
e.Message.BodyEncoding = Encoding.GetEncoding("iso-8859-9");
e.Message.Subject = "CodeInBox - New Password.";
e.Message.IsBodyHtml = true;
FileStream fs = new FileStream(Server.MapPath("./App_Data/mailBody.txt"), FileMode.Open);
StreamReader rd = new StreamReader(fs, Encoding.GetEncoding("iso-8859-9"));
string body = rd.ReadToEnd();
rd.Close();
fs.Close();
MembershipUser user = Membership.GetUser(PasswordRecovery1.UserName);
body = body.Replace("<% UserName %>", user.UserName);
body = body.Replace("<% Password %>", user.ResetPassword(PasswordRecovery1.Answer));
e.Message.Body = body;
}
//mailBody.txt
.......
<br />
Üyelik Bilgileri:<br />
--------------------------------------------------------------<br />
<strong>Kullanıcı Adı :</strong>
<% UserName %>
<br />
<strong>Parola :</strong>
<% Password %>
<br />
--------------------------------------------------------------<br />
<br />
........
Bir kelimenin yada sözcüğün harflerinin yerlerini değiştirerek yeni bir kelime yada sözcük elde etme durumuna Anagram denir.Yunanca bir kelime olan anagramma' dan gelir.
Örneğin, Vin Diesel 'I End Lives' yada Bahri 'İhbar' gibi.
Bu mantık ile bir uygulama yapmak istersek iki adet string dizisi tanımlamak gerekir;
string[] orginal = { "Cüneyt Arkın", "Sabah", "günaydın" };
string[] reorganize = { "Erhan Üncıy", "Hasba", "Aydın Gün" };
Şimdi mantığı biraz değiştirerek ve basit bir de algoritma ile uygulamayı daha dinamik bir hale nasıl getirebiliriz ona bakalım.
Öncelikle orjinal kelimeleri ';' noktali virgül ile ayırarak text dosyasına kaydedelim. Bu sayede kelimelerimizde uygulama içinde statik olarak kalmayacak.

Dosyadaki kelimeleri bir diziye atayalım.
string[] kelimeler = N';
private void Form1_Load(object sender, EventArgs e)
{
kelimeler = File.ReadAllText("kelimeler.txt", Encoding.GetEncoding(1254)).Split(';');
}
Daha sonra basit bir metot yazarak sırası ile dizideki kelimelerin harflerini karıştırarak yeni kelimeler elde edelim. Buradaki durum anagram da olduğu gibi mantıklı değil fakat harf kaybı olmaksızın yeni kelimeler elde etmek olacak. Metot, kelimedeki harfleri değil de harflerin indexlerini karıştıracaktır. Bu sayede kelime içinde bir harfin birden fazla olması durumunda ekstra kod yazmamız gerekmeyecek.

string kelimeKaristir(string kelime)
{
string yeniKelime = string.Empty;
string[] indexes = new string[kelime.Length];
int index = 0;
Random rnd = new Random();
while (index < kelime.Length)
{
int sayi = rnd.Next(kelime.Length);
if (Array.IndexOf(indexes, sayi.ToString()) == -1)
indexes[index++] = sayi.ToString();
}
for (int i = 0; i < indexes.Length; i++)
yeniKelime += kelime[Convert.ToInt32(indexes[i])].ToString();
return yeniKelime;
}
Burada her nekadar dizi içinde tutulacak değerler tam sayı olsada ben string tipini tercih ettim. Sebebi ise, int veri türünün başlangıç değeri 0 olduğundan 0 nolu indeks değerinin kontrolünün yapılmasının kolay olmasıdır.

Kodun tamamı;
anagramgame.rar
Kaynak : Wikipedia
Dizinin belli bir kısmını yeni bir diziye kopyalama şeysi, mp3 Tag ver.1 bilgisi almak için de örnek:
string path = @"D:\Music\Cincinnati Pops Orchestra-Erich Kunzel, Cond\The Great Fantasy Adventure Album\17 Conan the Barbarian- Anvil of Crom.mp3";
byte[] music = File.ReadAllBytes(path);
byte[] tagInfo = new byte[128];
Array.ConstrainedCopy(music, music.Length - 128, tagInfo, 0, 128);
İki tarih arasında ki hafta sonu gün sayısı kaç adettir?
Aradım bulamadım, .Net Framework içinde hazır bit metod yok :)
DateTime dt = DateTime.Now;
DateTime dt2 = DateTime.Now.AddDays(19);
TimeSpan sp = dt2 - dt;
int counter = 0;
for (int i = 0; i < (int)sp.TotalDays; i++)
{
DateTime t= dt.AddDays(i);
if (t.DayOfWeek == DayOfWeek.Sunday || t.DayOfWeek == DayOfWeek.Saturday)
counter++;
}
MessageBox.Show(counter.ToString());
Windows uygulamalarında sıkça kullandığımız MessageBox.Show() birkaç adım la webform larında kullanılabiliyormuş.Şöyleki.
öncelikle projemize System.Windows.Forms namespace ini ekliyoruz.
protected void Button1_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Google", "Google.com' a gider", MessageBoxButtons.YesNo) == DialogResult.Yes)
Response.Redirect("http://www.google.com.tr");
}
pek mantıklı değil:)
CloseConnection ne işe yarar neden kullanılır?
Command nesnesinin executeReader metotu ile kullanılan enum olarakta bilinir. Varsayılan değeri Default fakat ihtiyaç gereği 6 adet daha kullanılan değeri mevcuttur ki CloseConnection bunlardan biridir. Command nesnesine bağlı olan Connection nesnesi reader nesnesi kapatılana kadar açık kalır. Neden kalsın ki?
Örnek bir kullanım ile açıklayalım;


Kazancımıza bakalım;
- Reader ile okumanın Adapter ile okumaktan daha hızlı olduğunu herkes bilir. + 1
(Connection nesnesi kapansaydı Reader nesnesi N' olarak gelecekti. Açık bırakırsak ayrı bir dert)
- SqlCommand nesnesini Program nesnesine çekersekte uygulama System.Data.SqlClient' a bağımlı kalacaktı bu da iyi bir tasarım olmayacaktı. + 2
Hep yazmak istemişimdir, kısmet bu geceymiş :)
...
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
...
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
private void button1_Click(object sender, EventArgs e)
{
Thread kanal = new Thread(new ThreadStart(mailAl));
kanal.Start();
}
int len = 0;
byte[] baytar(string text)
{
byte[] donen = Encoding.ASCII.GetBytes(text);
len = donen.Length;
return donen;
}
private void mailAl()
{
TcpClient pop3 = new TcpClient("mail.ayrilmaz.com", 110);
NetworkStream ns = pop3.GetStream();
StreamReader rd = new StreamReader(ns);
listBox1.Items.Add(rd.ReadLine());
ns.Write(baytar("USER emre@ayrilmaz.com\r\n"), 0, len);
listBox1.Items.Add(rd.ReadLine());
ns.Write(baytar("PASS xxxxxxx\r\n"), 0, len);
listBox1.Items.Add(rd.ReadLine());
ns.Write(baytar("STAT\r\n"), 0, len);
listBox1.Items.Add(rd.ReadLine());
ns.Write(baytar("RETR 1\r\n"), 0, len);
listBox1.Items.Add(rd.ReadLine());
string satir = string.Empty;
do
{
satir = rd.ReadLine();
textBox1.Text += satir + "\r\n";
} while (satir != ".");
}
Kurulum sırasında uygulamanın kullanacağı veritabanı bağlantı bilgisi nasıl elde edilir?
Önce;
Setup projesinin UserInterface Editör' üne bir adet TextBoxes (A) formu ekleyelim. Bunu Installation Folder dialoğun üstüne alalım ve özellikleri resimdeki gibi eşitleyelim,

Değerleri installation class' taki metoda geçirmek için Custom Action Editör' üne Install Action ekleyelim ve CustomActionData özelliğini resimdeki gibi ayarlayalım.

Sonra;
Projemize bir adet Insaller Class ekleyelim. OnAfterInstall metodunu ezip gerekli kodları yazalım,
protected override void OnAfterInstall(System.Collections.IDictionary savedState)
{
string data = Context.Parameters["cs"];
string[] datas = data.Split(';');
string value = string.Format("Data Source={0};Initial Catalog=northwind;uid={1};pwd={2};", datas[0], datas[1], datas[2]);
Assembly thisAss = Assembly.GetExecutingAssembly();
string path = thisAss.Location.Replace(thisAss.GetName().Name + ".exe", thisAss.GetName().Name + ".exe.config");
XmlDocument doc = new XmlDocument();
doc.Load(path);
doc.SelectSingleNode("/configuration/connectionStrings/add[@name='strConn']").Attributes["connectionString"].Value = value;
doc.Save(path);
base.OnAfterInstall(savedState);
}

Kurulum sırasında kullanıcının belirlediği değerler, App.config dosyasındaki ConnectionString özelliğine yazılacaktır.
TextBox ın üzerine sürüklenen dosyanın yolunu almak.
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
if (e.Effect == DragDropEffects.Link)
{
object o = e.Data.GetData(DataFormats.FileDrop);
textBox1.Text = ((string[])o)[0];
}
}
Ajax Control Toolkit Slider için örnek düşünürken jpeg sıkıştırması gayet güzel olur dedim.
using System.Drawing;
using System.Drawing.Imaging;
.....
Bitmap bmp = new Bitmap(Server.MapPath("tempClock.jpg"));
ImageCodecInfo codec = N';
foreach (ImageCodecInfo cod in ImageCodecInfo.GetImageEncoders())
{
if (cod.MimeType == "image/jpeg")
codec = cod;
}
//long tipinde 0-100 arası
EncoderParameter Qpar = new EncoderParameter(Encoder.Quality,50L);
//int tipinde 0-23 arası
EncoderParameter Rpar = new EncoderParameter(Encoder.RenderMethod,(int)EncoderValue.RenderProgressive);
EncoderParameters Epars = new EncoderParameters(2);
Epars.Param[0] = Qpar;
Epars.Param[1] = Rpar;
bmp.Save(Server.MapPath("Clock.jpg"),codec,Epars);
EncoderValue Enumeration
GridView de Tooltip kullanımı için bir alternatif.
Tooltip olarak gösterilecek alanı DataKeyNames de saklayıp uygun kolona attribute ile eşleştirmek.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[2].Attributes.Add("title", GridView1.DataKeys[e.Row.RowIndex][0].ToString());
}
}
Yerel Pc' nin Versiyon 4 Ip adresini almak.
IPHostEntry en = Dns.GetHostEntry(Environment.MachineName);
var ip = en.AddressList.Where
(p => p.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First();
txtIP.Text = ip.ToString();
Windows uygulamalarında klasör ve dosyaları listelemek için sıkça kullanılan TreeView kontrolünü aynı iş için Asp.Net ortamında nasıl kullanabiliriz?
Web formuna ToolBox -> Navigation -> TreeView kontrolü ekleyelim ve kod tarafına geçelim. Oncelikle bir adet recursive metod yazalım (System.IO eklemeye unutmayalım).
void feelIT(DirectoryInfo[] folders, TreeNode node)
{
for (int i = index; i < folders.Length; i++)
{
TreeNode folderNode = new TreeNode(folders[i].Name, folders[i].FullName);
node.ChildNodes.Add(folderNode);
FileInfo[] files = folders[i].GetFiles();
foreach (FileInfo file in files)
{
TreeNode fileNode = new TreeNode(file.Name, file.FullName);
folderNode.ChildNodes.Add(fileNode);
}
try
{
feelIT(folders[i].GetDirectories(), node.ChildNodes[i]);
}
catch
{
;
}
}
}
Bu metod başlangıç yolundan itibaren ne kadar klasör ve altında da ne kadar dosya varsa bitine kadar çalışacaktır.
Fakat ortamın web olmasından dolayı bulunduğu index i bilemeyecektir.
O yüzden viewstate tabanlı bir propertie yazalım.
public int index
{
get
{
if (ViewState["index"] == N')
ViewState["index"] = 0;
return (int)ViewState["index"];
}
set
{
ViewState["index"] = value;
}
}
Lets list the files that are on the start way.
public void restIT(DirectoryInfo folders, TreeNode node)
{
FileInfo[] files = folders.GetFiles();
foreach (FileInfo file in files)
{
TreeNode rootFileNode = new TreeNode(file.Name, file.FullName);
node.ChildNodes.Add(rootFileNode);
}
}
And lastly, well start the process.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DirectoryInfo folders = new DirectoryInfo(Server.MapPath("./"));
TreeNode node = new TreeNode("Site", Server.MapPath("./"));
trwExplorer.Nodes.Add(node);
feelIT(folders.GetDirectories(), trwExplorer.Nodes[0]);
restIT(folders, trwExplorer.Nodes[0]);
}
}
İşte sonuç.
Zengin içerikli elektronik postalar hazırlarken en büyük sıkıntı kaynağın tekrar okunup gövde (body) bilgisi olarak MailMessage nesnesine verilmesi diyebiliriz. Bu sıkıntıyı kolay bir şekilde atlatmanın yolu sanırım WebUserControl kullanmak olacaktır. Kullanalım o zaman :)
Verileri almak için kullanacağımız Stored Procedure;
ALTER procedure enUcuz10Urun
AS
SET ROWCOUNT 10
SELECT Products.ProductName + ' - ' + cast(Products.UnitPrice as varchar(10)) + ' YTL' as Urun
FROM Products
ORDER BY Products.UnitPrice
Mail içeriğini sağlayacak olan WebUserControl;
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="mailContent.ascx.cs"
Inherits="feb.mailContent" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<h1 style="color: Red;">
Sizin için seçtiklerimiz !</h1>
<h3 style="color: Green;">
En Ucuz 10 ürün :)</h3>
<%
using (SqlConnection cn = new SqlConnection("Data Source=.;Initial Catalog=Northwind;Integrated Security=True"))
{
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandText = "enUcuz10Urun";
cm.CommandType = CommandType.StoredProcedure;
cm.Connection.Open();
using (SqlDataReader rd = cm.ExecuteReader())
{
while (rd.Read())
{
%>
<ul type="circle" style="font-family:Verdana;font-size:12px;">
<li>
<%=rd[0].ToString()%></li>
</ul>
<%
}
}
}
}
%>
<br />
<a href="http://www.northwind.com">Northwind</a>
Kontrolün toString metodunu tekrar yazarak (override) kullanım kolaylığı sağlıyoruz;
public override string ToString()
{
TextWriter tw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(tw);
this.RenderControl(htw);
return tw.ToString();
}
son olarak e-maili gönderecek olan kodlar;
protected void btnSend_Click(object sender, EventArgs e)
{
string to = "ilgili@karsifirma.com";
string subject = "En Ucuz 10 ürün";
mailContent mc = (mailContent)LoadControl("mailContent.ascx");
string body = mc.ToString();
MailMessage mail = new MailMessage("info@bizimFirma.com", to, subject, body);
mail.IsBodyHtml = true;
mail.SubjectEncoding = Encoding.GetEncoding(1254);
mail.BodyEncoding = Encoding.GetEncoding(1254);
SmtpClient smtp = new SmtpClient("mailServer");
smtp.Credentials = new NetworkCredential("userName", "passWord");
try
{
smtp.Send(mail);
}
catch
{
;
}
}
Linq to xml ile bir xml dosyası oluşturup çalışma zamanı da Treeview kontrolünde gösterelim.
//aspx
<body>
<form id="form1" runat="server">
<div>
<asp:TreeView ID="TreeView1" runat="server">
<DataBindings>
<asp:TreeNodeBinding DataMember="Categories" Text="Categories" />
<asp:TreeNodeBinding DataMember="Category" TextField="CategoryName" ValueField="CategoryID" />
</DataBindings>
</asp:TreeView>
</div>
</form>
</body>
//cs
private void bindTree()
{
northwindDataContext db = new northwindDataContext();
string path = Server.MapPath(".\\App_Data\\data.xml");
if (!File.Exists(path))
{
XDocument xdoc = new XDocument(
new XDeclaration("1.0", "utf-8","yes"),
new XElement("Categories",
from p in db.Categories
orderby p.CategoryName
select
new XElement("Category",
new XAttribute("CategoryID", p.CategoryID),
new XAttribute("CategoryName", p.CategoryName))));
xdoc.Save(path);
}
XmlDataSource xd = new XmlDataSource();
xd.ID = "xid1";
xd.DataFile = path;
this.form1.Controls.Add(xd);
TreeView1.DataSourceID = "xid1";
}
Yazılımcı site yapar, çoklu dil desteği yapar. Birde yanına SiteMapPath olsun ister.
Bu durum da SiteMapPath kontrolü için en önemli problem 2 adet .sitemap dosyasının olması ve hangisini kullanacağını bilememesidir. Bu durumu aşmanın yolu web.config dosyasına her bir sitemap için provider tanımlamaktır.
//web.config
<siteMap defaultProvider="sitemapTR">
<providers>
<add name="sitemapTR" type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile="Web_tr.sitemap" description="türkçe"/>
<add name="sitemapEN" type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile="Web_en.sitemap" description="english"/>
</providers>
</siteMap>
Tanımlanan providerları tarayıcının kullandığı dile göre kontrole eşitlemek işin son kısmı olacaktır.
string provider = string.Format("sitemap{0}", Thread.CurrentThread.CurrentUICulture.Name.Substring(0, 2).ToUpper());
SiteMapPath1.SiteMapProvider = provider;
VS2005 SP1 ile New Project -> Web altında gelen Web Application üzerinden uygulaması geliştiriyorsak Profile kullanımı ne yazık ki Web Site ile kullanımından çok farklı bir hal alıyor. Peki bu hal nasıl ona bakalım;
Önce web.config dosyasında birkaç küçük ayar yapıyoruz:
<anonymousIdentification enabled="true"/>
<profile defaultProvider="mySqlProfileProvider" enabled="true">
<providers>
<clear/>
<add name="mySqlProfileProvider" connectionStringName="codeConnectionString" applicationName="/" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
<properties>
<add name="ad" allowAnonymous="true"/>
<add name="soyad" allowAnonymous="true"/>
<add name="dogumTarihi" type="DateTime" allowAnonymous="true"/>
<add name="blog" allowAnonymous="true"/>
<add name="ulke" allowAnonymous="true"/>
</properties>
</profile>
Daha sonra ise kod kısmında, örneğin kullanıcı kayıt sırasında değerleri eşitlemek istersek;
MembershipCreateStatus stat;
Membership.CreateUser(txtUN.Text.Trim(), txtPWD.Text.Trim(), txtMail.Text.Trim(), txtSQ.Text.Trim(), txtANS.Text.Trim(), true, out stat);
lblMesaj.Text = userCreateStat(stat);
if (stat == MembershipCreateStatus.Success)
{
Roles.AddUserToRole(txtUN.Text.Trim(), "coder");
FormsAuthentication.SetAuthCookie(txtUN.Text.Trim(), false);
Context.Profile.SetPropertyValue("ad", txtName.Text.Trim());
Context.Profile.SetPropertyValue("soyad", txtLast.Text.Trim());
Context.Profile.SetPropertyValue("blog", txtBlog.Text.Trim());
Context.Profile.SetPropertyValue("dogumTarihi", Convert.ToDateTime(txtDT.Text.Trim()));
Context.Profile.SetPropertyValue("ulke", DropDownList1.SelectedValue);
Context.Profile.Save();
...
GZipStream kullanırken sıkışacak ve açılacak dosya hakkında bilgi tutmak için (algoritmasında var olan mantığı kullanmak için ekstra özellik ve metod olmadığından) nesne olarak tasarlayıp serileştirip yollamak mantıklı bir çözüm olabilir.
önce:
//dosya - ClassLibrary
using System.Runtime.Serialization.Formatters.Binary;
...
[Serializable]
public class fileClass
{
public string fileName { get; set; }
public string fileExtension { get; set; }
public byte[] file { get; set; }
public string FullName
{
get
{
return fileName + "." + fileExtension;
}
}
}
//uygulama
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;
using zipClass;
...
class Program
{
static void Main(string[] args)
{
zip("c:\\Debug.txt");
//unzip("c:\\Debug.xip");
}
static void zip(string path)
{
fileClass newFile = new fileClass();
newFile.file = File.ReadAllBytes(path);
newFile.fileName = Path.GetFileNameWithoutExtension(path);
newFile.fileExtension = Path.GetExtension(path).Substring(1);
BinaryFormatter bf = new BinaryFormatter();
MemoryStream mem = new MemoryStream();
bf.Serialize(mem, newFile);
using (FileStream stream = File.Open(Path.ChangeExtension(path, "xip"), FileMode.Create))
{
using (GZipStream giz = new GZipStream(stream, CompressionMode.Compress))
{
byte[] buffer = mem.ToArray();
giz.Write(buffer, 0, buffer.Length);
}
}
}
static void unzip(string path)
{
MemoryStream mem = new MemoryStream();
using (FileStream stream = new FileStream(path, FileMode.Open))
{
using (GZipStream giz = new GZipStream(stream, CompressionMode.Decompress))
{
int read = giz.ReadByte();
while (read != -1)
{
mem.WriteByte((byte)read);
read = giz.ReadByte();
}
}
}
mem.Position = 0;
BinaryFormatter bf = new BinaryFormatter();
fileClass xipFile = (fileClass)bf.Deserialize(mem);
using (FileStream stream2 = File.Open(path.Replace(Path.GetFileName(path), xipFile.FullName), FileMode.Create))
{
using (BinaryWriter bw = new BinaryWriter(stream2))
{
bw.Write(xipFile.file);
}
}
}
}
Daha mantıklısı DeflateStream kullanmakmış:)
sonra:
static void zip(string path)
{
fileClass newFile = new fileClass();
newFile.file = File.ReadAllBytes(path);
newFile.fileName = Path.GetFileNameWithoutExtension(path);
newFile.fileExtension = Path.GetExtension(path).Substring(1);
using (FileStream stream = File.Open(Path.ChangeExtension(path, "xip"), FileMode.Create))
{
using (DeflateStream giz = new DeflateStream(stream, CompressionMode.Compress))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(giz, newFile);
}
}
}
static void unzip(string path)
{
fileClass xipFile = N';
using (FileStream stream = new FileStream(path, FileMode.Open))
{
using (DeflateStream giz = new DeflateStream(stream, CompressionMode.Decompress))
{
BinaryFormatter bf = new BinaryFormatter();
xipFile = (fileClass)bf.Deserialize(giz);
}
}
using (FileStream stream2 = File.Open(path.Replace(Path.GetFileName(path), xipFile.FullName), FileMode.Create))
{
using (BinaryWriter bw = new BinaryWriter(stream2))
{
bw.Write(xipFile.file);
}
}
}
Şöyle bir düşündüğümüzde veritabınında bulunan herhangi bir tablonun verilerini Xml biçiminde dosyaya yazmanın kaç yolu vardır acaba? Sabahları genelde işe erken gelirim, 1.5 saat kadar :).
Oturdum bir kaç örnek yaptım, paylaşıyorum tüm dünya ile. (Özgüvenin tavan yaptığı an)
Aklıma gelen ilk yöntem DataTable nesnesini kullanmak. Bu nesneyi sadece yazmak için kullanmak kaynak tüketimi açısından çok iyi bir seçim olmaz fakat kullanım kolaylığı açısında tercih edilebilir.

Diğer bir yöntem ise henüz Veri Katmanında (DataLayer) iken oracıkta xml formatına dönüştürüp XmlTextWriter ile cayır cayır yazmak.

Son yöntem ise daha önce şu yazıda kullandığım teknik ile (attribute yerine bu sefer node kullandım) XDocument ile manuel olarak xml dosyasını oluşturmak. Sanırım en zoru bu. Yanlış anlaşılmasın benim için kolay da hani ilk yapan için diyorum.

Web siteniz için yurt dışından host hizmeti alıyorsanız, DateTime (Structure) yapısının string metotları istediğiniz sonuçları döndürmeyebilir.
Bunun için örnek bir Extension Method hazırladım;


Koleksiyon doldurmak için başka bir alternatif


Daha önceleri MARS (Multiple Active Result Sets) uygulamalarımı Treeview yada Listbox kontrollerini kullanarak yapıyordum. Listview içinde sıralama ile uğraşırken bir örnekte bu kontrolle yapayım dedim.




Kötü emelleri olan bir öğrencim için derste geliştirdiğimiz bir uygulama. Kısaca anlatmak gerekirse, sisteme tıkalacak çıkarılabilir usb flash diskleri gözlemleyip içeriğini kopyalayan basit anlamda casus yazılım :)
Örnek proje.

Çok yakın ve kadim bir dostum için araştırırken farkettim ve paylaşmak istedim.
ListView kontrolü içinde ki verileri gruplayarak göstermek. DataList kontrolündeki RepeatColums özelliğini kullanmak gibi fakat birazcık farklı :)
Div etiketleriyle Listview'e şablon hazırlamak lazım.

Veri kaynağı için basit ve hızlı bir çözüm, dosyalar.

Dosyaları biraz süslü gösterelim.
![]()
Sonuç;
CheckForIllegalCrossThreadCalls = false; ve Thread güvenliği can sıkıcı olursa;

Öğrencilerimin en sık sorduğu sorulardan biri de, veritabanında depolanmış resimleri web sayfasında nasıl gösterildiğidir. Internette bu konu hakkında zilyon tane yazı olmasına karşın bir tane yazma gereği hissettim.
Öncelikle anlaşılması gereken konu, html sayfalarında resim göstermenin ilk
koşulu resmin fiziksel yolunun kontrole yada etikete aktarılmasıdır.
Örneğin;
<
img src="/images/bullet.png" alt="Bullet" />
Diğer taraftan baktığımızda ki bu taraf veritabanı tarafıdır, resim gibi
içeriklerin hangi tip veri alanında saklanacağıdır.
C# ile yazılım geliştiryorsanız resim yada bir dosya serileştiğinde (yani
veritabına yazıldığında) byte dizisinden ibaret olacaktır.
Bu durumda en uygun alan tipi varbinary olsa iyi olur. :)
Kaçınılması gereken davranışlar.
<
yada
img1.ImageUrl = reader[1].ToString();hiç olmadı :)
img1.ImageUrl = command.ExecuteScalar().ToString();
Yapılması gereken gayet açık. Veritabınından okunan byte dizisini resim
formatında dışarı aktaracak (response) bir dosya (aspx,ashx)
oluşturmak ve oluşan dosyanın yolunu resmi gösterecek kontrol yada etikete
atamaktır.
Örnek tabloda gösterildiği gibi resim UrunResim alanında varbinary (byte dizisi) olarak saklanıyor.
Resmi oluşturacak resim.aspx sayfasına gönderilen parametre değeri ile veritabanında basit bir sorgu yapılarak ve sonucu byte dizisi olarak elde edilir.
protected void Page_Load(object sender, EventArgs e)Son olarak ise sayfa çıktısının resim olacağını işaret eder ve çıktıyı BinaryWriter metotu ile oluştururuz.
Ben Xml'i severim de herkes sevmek yada bilmek zorunda değil. Xml ile yaptığım anket uygulamasını Sql ve Ado.Net kullanarak tekrar yaptım.
Veritabanı şeması aynen aşağıdaki gibi;
Uygulamada kullanılan nesne diyagramı;
Uygulamada kullanılan örnek kod;

Uygulama kaynak kodları da burada.
Birden çok aşaması olan uygulamalarda geçici olarak dosya oluşturmak için metot yazmak yerine Path nesnesinin GetRandomFileName metotunu kullanabilirsiniz.
![]()
rd1gm02e.hyt
Bu dosyalarıda geçici bir yerde saklamak isterseniz de GetTempFileName metotu size işletim sisteminin geçici klasörü yolu ile birlikte geçici bir dosya adı döndürecektir.
![]()
C:\Users\Administrator\AppData\Local\Temp\tmpA116.tmp
Buradaki metotlar dosya oluşturmaz sadece isim oluşturur.
Hatasız bir uygulama yazmak için kullanıcıyı ortadan kaldırmaktır diye duymuştum bir zamanlar. Yazılımlarımızda hatalar olacak. Bu kaçınılmaz ama en aza indirmek içinde çaba sarfetmek te bizim görevimiz. Lakin bunun için heryere try cacth blokları da koymak pek mantıklı bir yaklaşım değil:)
Bu durumlar için, özellikle web uygulamalarında "Error Feedback" denilen bir yöntem çok sık kullanılır.
Amaç;
çalışma zamanı bir sayfa da yada ona bağlı bir uygulamada hata oluştuğunda, hata ile ilgili detayların geliştiriciye mail olarak gönderilmesi daha sonra da kullanıcıya hata mesajı yerine basit bir html sayfası gösterilmesinden ibaret.
Öncelikle ihtiyaçları belirleyelim. Yani hangi bilgilerin gönderilmesi gerekiyor bir bakalım.

Gönderilecek Feefback için güzle bir html şablonu oluşturalım. Şablon içinde bilgi gireceğimiz alanları küme parantez parametreleri ile işaretleteyim ki String nesnesini Format metotu ile rahatça kullanabilelim.
Daha iyi anlamak için Error nesnesi için yazdığımız yardımcı ErrorProvider nesnesine deki CreateMessage asdlı sabit metota göz atalım.

Herşey tamam gibi, sırada oluşabilecek hataları elde elebileceğimiz Global Application Class' ından yardım almaya geldi. Global.asax ' ın Application_Error adlı metotu, uygulama içinde hata oluştuğunda otomatik devreye girer. Bizde burada devreye girip ihtiyacımız olab kodları yazıyoruz.

Son bir adım kaldı. Kullanıcı hata mesajları yerine bizim belirlediğimiz sayfaları görsün istiyorsak;

web.config dosyası içindeki customError -> mode özelliğini On olarak değiştiririz. error alt düğümleri ile olası hatalar için uygun sayfaların yollarını redirect özellikleri ile belirttikten sonra uygulamada bitmiş oluyor. Çeşitlendirmek mümkün.
Örnek proje.
Öyle bir tablom olsun ki sınırsız kategori ve alt kategori ekleyebileyim. Neden bahsettiğimi anladınız sanırım :) Halk arasında Sınırsız Ağaç Yapısı denilen tablo çeşidi.
Örnek tablo:

Örneğimizdeki yapı şöyle olacak; Kategori hiyerarşinin en üstünde ise alt kategori değeri 0 (sıfır) olacak. Değilse üst kategorinin id değeri yer alacak.

Azıcık kod yazalım.
.png)
Sonuç;

Örnek proje.
Northwind sql eğitimlerinde sıkça kullandığım (basit yapısınsan dolayı) bir veri tabanı örneğidir. Aynı zamanda eskidir de :) En sık başvuru yaptığım tablolardan biri de Categories tablosudur. Bu tabloda ürün kategoriler resimleri ile yer almaktadır.

Yer almasına alıyor da, alırken ilk 78 ve son 78 byte kısmında ole nesne bilgisi olduğu için kimi zaman sorunlar yaşanıyor.

Her nekadar DataGridView kontrolü bunu otomatik gösterse de, manuel olarak PictureBox gibi bir kontrolde göstermek istersek şu şekilde kullanmak gerekiyor.

Örnek proje.
Repeater, veri kontrolleri içinde en sevdiğimdir. Onu esnek hale getiren basit yapısı ben en cezbeden özelliğidir. Basit olduğundan dolayı görevi sadece veri göstermek. Peki sıralama yapmak istersek ne yapmalıyız?
Aslında cevap basit; HeaderTemplate içine koyacağımız LinkButton kontrolleri ve sıralama bilgilerini ViewState içinde tutarak yapabilir.
Burada tablo başlıklarına birer LinkButton ve Image kontrolü koyuyoruz. LinkButton sıralama komutunu işlerken, Image kontrolleride sıralama yapılan satırları işaret edecek.

Sıralama sırasından iki adet bilgiye ihtiyaç var. Sıralanacak veri kolonu ve sıralama yönü. Bu bilgileri ViewState içinde saklıyoruz. Kullanım kolaylığı olması için Özellik (Property) olarak tanımlıyoruz.

Sıralama komutu için ado.net kodlarımız. Kolon adı parametre olmadığı için String nesnedinin Format metotunu kullandım.

Uygulama sonunda elde edeceğimiz veri listesi.

Kalan detaylara projeyi indirip bakabilirsiniz.
Projeyi indir.
Metotlar geriye değer döndürür yada döndürmez. Peki döndürenler kaç değer döndürür denildiğinde tabi ki bir deriz. Birden fazlaya ihtiyaç varsa ne yaparız? Bunun için 3 metot prototipi yazdım, paylaşıyorum.

İlk yöntem out parametre anahtarını kullanmak. Geriye dönmediği kesin ama metottan etkilendiğide bir gerçek. İşe yarıyor mu, evet :)

İkinci yöntem ise Classnesne (Custom Reference Type) kullanmak. Geriye yine tek bir nesne dönüyor. İçsel olarak genişletilebilmesi (property, field) sayesinde çok kullanışlı lakin yazması zahmetli.

Son yöntem aslında yazının amacı ve Framework 4.0 yeniliği olan Tupleçok-ögeli kullanmak...
Örnek proje.