Ana Sayfa >> ASP.Net >> ASP.Net ile Online Test
Kategoriler
 ASP.Net
 C#.Net
 VB.Net
 SQL Server
 SQL Script
 Eğlence
 Haberler
 Görsel Ders
 Ücretsiz Programlar
 Diğer

Dost Siteler
 Volkan KORKMAZ
 Sem GÖKSU
 Mustafa Altuntaşlar
 Adnan TÜRK
 Ergün YÜCEL
 Koray KOCABAŞ
 Yazılım Uzmanı
 Yaz Geliştir
 Yazılım Günlüğü
 Code Project

Takvim
<Temmuz 2010>
PztSalÇarPerCumCmtPaz
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

Hakkımda
Windows Live Alerts
 E-Posta
 Msn ( )
 Skype


Login with Facebook
 
 ASP.Net ile Online Test

Bu makalemizde Online Test Sistemi konusuna değineceğiz. Kısaca Test, bir ölçme aracıdır. Bizde yapacağımız sistemle Online Sınav, Test,  Anket gibi işlemleri yapabileceğiz. Bilgilerimizi dinamik olarak veritabanımızdan alacağız.  Bunun için öncelikle veritabanımızı aşama aşama oluşturalım.




Tablo: Testler

TestID int  = Tekil değerimiz
Adi varchar(50) = Test Adı, Başlığı vs…
BaslangicTarihi smalldatetime = Testin başlayacağı tarih
BitisTarihi smalldatetime = Testin biteceği tarih

 

Tablo: TestSorulari

TestSoruID int = Tekil değerimiz
TestID int = Sorunun hangi test’e ait olduğunu tuttuğumuz alan
Baslik varchar(100) = Soru Başlığı...
 SoruTipi varchar(50) = Soru cevabı için kullanılacak control tipi. Ör: RadioButtonList, TextBox

 

Tablo: SoruSecenekleri

SoruSecenekID int = Tekil değerimiz
TestSoruID int = Seçeneğin hangi soru’ya ait olduğunu tuttuğumuz alan
Baslik varchar(100) = Seçenek Başlığı...
DogruCevap bit = Seçeneğin doğru olup olmadığını tuttuğumuz alan

 

Tablo: TestCevaplari

TestCevapID int = Tekil değerimiz
TestSoruID int = Cevabın hangi soru’ya ait olduğunu tuttuğumuz alan
SoruSecenekID int = Cevabı tutulduğu alan
SoruText varchar(100) = Metin olarak girilecek cevaplar için
UserID int = Cevabı veren kişi bilgisi için
KayitTarihi smalldatetime = Cevabın kayıt tarihi

Kısaca veritabanımızı özetleyelim, Testler tablosunda testin genel bilgilerini tutacağız. Daha sonra TestSorulari tablosu ile teste ait soruları tutacağız. Bu kısımda dikkat edilmesi gereken nokta SoruTipi olacak. Bu alanda RadioButtonList, TextBox hatta çoklu seçimler için CheckBoxList bile kullanabiliriz. Seçtiğimiz tipe göre SoruSecenekleri tablosunu kullanarak soruların detaylarını tutacağız. Son olarakta kullanıcının verdiği bilgileri göre TestCevaplari tablosunu kullanarak bilgileri db’mize kaydedeceğiz.

Ben aşağıdaki gibi bilgileri veritabanına kayıt ettim. Makale sonunda SQL Script’i ile sizde örneklere göz atabileceksiniz.

Testler.jpg

TestSorular.jpg

TestSecenekler.jpg

Gelelim HTML Dizayn ve kodlarımıza…

Defaut.aspx


<
asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="upTestPanel" runat="server">
  <ContentTemplate>
    <asp:Repeater ID="rptTest" runat="server" OnItemDataBound="rptTest_ItemDataBound">
      <ItemTemplate>
        <div style="height: 25px; width: 100%; background-color: #f8f8f8; 
        vertical-align: middle; border-bottom: solid 1px #808080">
          <%#Eval("Baslik") %> <asp:LinkButton ID="lnkTemizle" runat="server" 
          OnClick="lnkTemizle_Click" Text="Temizle"></asp:LinkButton>
        </div>
        <div style="padding: 3px 0px 3px 0px;">
          <asp:RadioButtonList ID="rbl" runat="server" Visible="false" />
          <asp:TextBox ID="txt" runat="server" Visible="false" />
          <asp:HiddenField ID="TestSoruID" runat="server" Value='<%#Eval("TestSoruID") %>' />
          <asp:HiddenField ID="SoruTipi" runat="server" Value='<%#Eval("SoruTipi") %>' />                    
        </div>
      </ItemTemplate>
      <FooterTemplate>
        <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Oyla" />
      </FooterTemplate>
    </asp:Repeater>
  </ContentTemplate>
</asp:UpdatePanel>
   

HTML Görünüm

 
HtmlGorunum.jpg
  

 

Default.aspx.cs

 
private
int TestID;

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        GetAktifTest();
        GetTestSorulari();
    }
}

private
void GetAktifTest()
{
    SqlConnection con = new SqlConnection("ConnectionString...");
    //Başlangıç tarihinden Büyük, Bitiş tarihinden küçük geçerli testi buluyoruz
    //Mantıken bir tane kayıt geri dönmeli, eğer birden fazla kayıt dönerse 
    //ilk değeri almış oluruz. Bu yüzden test eklerken tarihlere dikkat etmelisiniz!
    SqlCommand com = new SqlCommand("Select * From Testler Where BaslangicTarihi < GetDate() and BitisTarihi > GetDate()", con);
    SqlDataReader dr;
    con.Open();
    dr = com.ExecuteReader();
    if (dr.HasRows)
    {
        dr.Read();
        //Geçerli testin ID'sini alıyoruz, bu değere göre biraz sonra soruları dolduracağız...
        //Değişken global tanımlı diğer methodlardada kullanacağız...
        TestID = Convert.ToInt32(dr["TestID"].ToString());
        dr.Close();
    }
    else
    {
        //Geçerli testin bulunmadığı blok...
        Response.Redirect("blabla...aspx");
    }
    con.Close();
}

private
void GetTestSorulari()
{
    SqlConnection con = new SqlConnection("ConnectionString...");
    //Teste ait soruları çekiyoruz
    SqlDataAdapter da = new SqlDataAdapter("Select * From TestSorulari Where TestID=@TestID", con);
    da.SelectCommand.Parameters.AddWithValue("@TestID", TestID);
    DataTable dt = new DataTable();
    da.Fill(dt);
    rptTest.DataSource = dt;
    //Soruları Repeatırımıza eşitledikten sonra ItemDatabound eventında 
    //Seçenekleri oluşturmaya başlayacağız...
    rptTest.DataBind();
}

private
DataTable GetSoruSecenekleri(int TestSoruID)
{
    SqlConnection con = new SqlConnection("ConnectionString...");
    //Soruya göre seçeneklerini yüklüyoruz...
    SqlDataAdapter da = new SqlDataAdapter("Select SoruSecenekID, Baslik From SoruSecenekleri Where TestSoruID=@TestSoruID", con);
    da.SelectCommand.Parameters.AddWithValue("@TestSoruID", TestSoruID);
    DataTable dt = new DataTable();
    da.Fill(dt);
    return dt;
}

protected
void rptTest_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        //Databind() eventından sonra eşitlediğimiz değerlere erişiyoruz
        int TestSoruID = Convert.ToInt32((e.Item.FindControl("TestSoruID") as HiddenField).Value);
        //Makalede söylediğimiz gibi SoruTipi'ni hangi controle seçenekleri
        //yükleyeceğimizi kontrol edeceğiz...
        string SoruTipi = (e.Item.FindControl("SoruTipi") as HiddenField).Value;
        if (SoruTipi == "RadioButtonList")
        {
            //Item içindeki RadioButtonListi kontrolünü buluyoruz
            RadioButtonList rbl = e.Item.FindControl("rbl") as RadioButtonList;
            //Bulduğumuz controle seçenekleri yüklüyoruz...
            rbl.DataSource = GetSoruSecenekleri(TestSoruID);
            rbl.DataTextField = "Baslik";
            rbl.DataValueField = "SoruSecenekID";
            rbl.DataBind();
            //Daha önce yaratılan ancak gizli olan RadioButtonListimizi gösteriyoruz...
            rbl.Visible = true;
        }
        else if (SoruTipi == "TextBox")
        {
            //Item içindeki TextBox kontrolünü buluyoruz
            TextBox txt = e.Item.FindControl("txt") as TextBox;
            //Daha önce yaratılan ancak gizli olan TextBoxımızı gösteriyoruz...
            txt.Visible = true;
        }
    }
}

protected void Button1_Click(object sender, EventArgs e)
{
    //Bu kısımda Repeater içinde oluşturulan sorular içinde dönüyoruz
    foreach (RepeaterItem RI in rptTest.Items)
    {
        //DataBound işleminde yaptığımız gibi Soru bilgilerine erişiyoruz...
        int TestSoruID = Convert.ToInt32((RI.FindControl("TestSoruID") as HiddenField).Value);
        string SoruTipi = (RI.FindControl("SoruTipi") as HiddenField).Value;
        //Aynı şekilde soru tipine göre cevaba nasıl erişeceğimizi belirliyoruz
        //Ör. Bu kısımda CheckBoxList kullanmış olsaydık kontrolü bulduktan sonra
        //onun içindede dönüp seçili olanları bulup kayıt işlemini gerçekleştirecektik...
        if (SoruTipi == "RadioButtonList")
        {
            RadioButtonList rbl = RI.FindControl("rbl") as RadioButtonList;
            //Eğer seçili bir değer varsa bunu rbl.SelectedValue ile alıp
            //Veritabanımızdaki TestCevaplari tablosundaki SoruSecenekID kolonuna yazacağız.
            if (rbl.SelectedIndex != -1)
            {
                int SoruSecenekID = Convert.ToInt32(rbl.SelectedValue);
                Oyla(TestSoruID, SoruSecenekID, "", "1");
            }
            //Boş ise değer göndermiyoruz...
            else
            { Oyla(TestSoruID, 0, "", "1"); }
        }
        else if (SoruTipi == "TextBox")
        {
            //RadioButtonList'deki gibi aynı kontrolleri yapıp cevaplama işlemini gerçekleştiriyoruz.
            TextBox txt = RI.FindControl("txt") as TextBox;
            if (!String.IsNullOrEmpty(txt.Text))
            {
                string SoruText = txt.Text;
                //Ancak bu kısımda SoruText alanına kayıt yapıyoruz...
                Oyla(TestSoruID, 0, SoruText, "1");
            }
            else
            { Oyla(TestSoruID, 0, "", "1"); }
        }
    }
}

private
void Oyla(int TestSoruID, int SoruSecenekID, string SoruText, string UserID)
{
    SqlConnection con = new SqlConnection("ConnectionString...");
    //Gelen değerleri veritabnımıza kayıt ediyoruz...
    SqlCommand com = new SqlCommand("INSERT TestCevaplari VALUES(@TestSoruID, @SoruSecenekID, @SoruText, @UserID, GetDate())", con);
    com.Parameters.AddWithValue("@TestSoruID", TestSoruID);
    if (SoruSecenekID > 0) { com.Parameters.AddWithValue("@SoruSecenekID", SoruSecenekID); }
    else { com.Parameters.AddWithValue("@SoruSecenekID", DBNull.Value); }
    if (!String.IsNullOrEmpty(SoruText)) { com.Parameters.AddWithValue("@SoruText", SoruText); }
    else { com.Parameters.AddWithValue("@SoruText", DBNull.Value); }
    com.Parameters.AddWithValue("@UserID", UserID);
    con.Open();
    com.ExecuteNonQuery();
    con.Close();
}

protected
void lnkTemizle_Click(object sender, EventArgs e)
{
    //Bu kısmı seçtiğimiz değerleri temizlemek için kullanacağız
    //Repeater içinden gelen Butonu yakalıyoruz...
    LinkButton lnkTemizle = (LinkButton)sender;
    //Hangi Itemdan geldiğini buluyoruz...
    RepeaterItem RI = (RepeaterItem)lnkTemizle.NamingContainer;
    //Yine aynı şekilde DataBound ve Oylama işlemindeki gibi SoruTipine göre
    //kontrolü yakalayıp seçili yada yazılı değerleri siliyoruz...
    string SoruTipi = (RI.FindControl("SoruTipi") as HiddenField).Value;
    if (SoruTipi == "RadioButtonList")
    {
        RadioButtonList rbl = RI.FindControl("rbl") as RadioButtonList;
        rbl.SelectedIndex = -1;
    }
    else if (SoruTipi == "TextBox")
    {
        TextBox txt = RI.FindControl("txt") as TextBox;
        txt.Text = "";
    }
}
 
  

Sonuç…

TestCevaplar.jpg

Bu tabloya göre anket, test, sınav vs.. gibi sistemlerde sonuçlarınızı yorumlayabilirsiniz…

Ör. Belli bir kullanıcının verdiği cevapların kaç yanlış ya da doğru yaptığını öğrenmek için aşağıdaki gibi bir sorgu kullanabilirsiniz.

Select TC.TestSoruID, TC.SoruSecenekID, TC.SoruText, SS.DogruCevap
From TestCevaplari as TC
Left Join SoruSecenekleri as SS On SS.SoruSecenekID = TC.SoruSecenekID
Where TC.UserID='1'

Cevap2.jpg

Yorumlayacak olursak 1 no’lu kullanıcı 1 yanlış, 1 doğru cevap verdiğini. Yorum olarakta “Güzel test…” mesajını bize yolladığını görebiliriz...

Başka bir makalemde görüşmek dileğiyle...

Gökhan BAĞCI
Microsoft Certified Professional

Eklenme Tarihi: 18.01.2008 23:18:00
Yorum Yaz
Gönderen
Başlık
Yorum


Yorumlar
Tşk...
Gökhan hocam'ı tebrik ediyorum her zamanki gibi süper bir yeni makale yayınlamış. Devamını bekliyoruz!
Yazan: Derman , Tarih: 20.01.2008
Tebrikler
Güzel bi konuya değinmişsin... Eline sağlık
Yazan: Sem Göksu , Tarih: 21.01.2008
güzel..
çok güzel bir çalışma.tşk.
Yazan: hakan , Tarih: 30.01.2008
Teşekkürler
Merhaba sayın hocam. Süper bir makele olmuş. Bende şuan da bir online test sitesi yapmaktayım ama sizinki kadar başarılı gidemiyorum. Acaba bu uygulamanın projesini gönderebilirmisiniz? Daha iyi inceleyebilmek için. (mustafacicek18@gmail.com)
Yazan: mstfcck , Tarih: 04.02.2009
Teşekkür
Çalışma çok yararlı gerçekten.Eline sağlık.
Yazan: Ali Akgül , Tarih: 05.06.2009

merhaba çok iyi bir çalışma bende şu an online test ile ilgileniyorum ve çok faydalı oldu... tşk... uygulamanın projesini göndermeniz mümkünmü veya faydalanabileceğim kaynak oztarhan21@hotmail.com
Yazan: , Tarih: 07.08.2009


Etiketler
asp.net, online test



2006-2008 © Gökhan BAĞCI
Tüm hakları saklıdır.