Solved

Recommendations and advice on creating an online assessment/exam

Posted on 2008-06-24
4
868 Views
Last Modified: 2013-11-07
Hi all,

Can I get some advice on creating an online assessment/exam? I currently have a ASPX page which is comprised as follows:

1. I have an asp:Panel (ID pnlAssessment).
2. I have the questions and answers stored in 2 tables (SQL Server 2005), each in a question and answer table respectively.
3. A question can have 2 types, a multiple choice or an image question. If it is multiple choice there can be many prospective answers, and more than one may be correct.

The way I am doing this at the moment is building a dataset of 2 datatables with a relation between the questions and answers. I then dynamically create a CheckBoxList for each question, with each answer a ListItem.

Here is the crux of the problem, when submitting your answer I attempt to iterate through all the controls on the page, and pull all the answers into a database answers table. This used to work. I submitted a question to EE a while ago because the For Next loop was not finding the controls on the page. I went through mountains of testing and changing code to try and get this too work, I even got Microsoft involved through paid support. In the end, through sheer desperation, I created a new page and copied the code across and the For Next found the controls and submitted the answers. As of yesterday this has stopped working again! So now I am questioning whether this is even the right/most efficient way to do it and I am looking for your help before I kill myself!

I've attached my current code so you can see how it used to work. Hopefully you'll have some suggestions? I wish I could assign 5000 points as this is now so desperate.

Thanks.
<%@ Page Language="VB" MasterPageFile="~/secure/masterpages/2-col-v3.master" AutoEventWireup="false" CodeFile="assessment-4-v3.aspx.vb" Inherits="secure_assessments_precourse_assessment_4_v3" title="Untitled Page" %>
 
<asp:Content ID="Content1" ContentPlaceHolderID="cphNew2ColMain" Runat="Server">
    <div class="pagetitle">
        <asp:Image ID="imgAssessment" ImageAlign="Middle" ImageUrl="~/App_Themes/jcb-v3/images/pageicons/assessment.gif" runat="server" />&nbsp;
        <asp:Label ID="lblOnlineAssessment" Text="Online Assessment" runat="server"></asp:Label>
    </div>
 
    <asp:Panel ID="pnlAssessment" EnableViewState="true" CssClass="formwrapper" runat="server"></asp:Panel>
 
    <div class="forminput">
        <asp:Button ID="btnSubmitAnswers" Text="Submit Answers" runat="server" />
    </div>
</asp:Content>
 
<asp:Content ID="Content2" ContentPlaceHolderID="cphNew2ColRight" Runat="Server">
    <div class="rightsubtitlebar">
        <asp:Label ID="lblAssessmentSubTitle" Text="Assessment Started" SkinID="subtitle" runat="server"></asp:Label>
    </div>
 
    <div class="pagetext">
        <asp:Label ID="lblAssessmentWarning" Text="{not loaded}" Font-Bold="true" SkinID="fielderror" runat="server"></asp:Label>
    </div>
</asp:Content>
 
Protected Sub getAssessmentQuestions()
        Dim courseID As Integer = 31
 
        Dim con As New SqlConnection(ConnectionStrings("dev").ConnectionString)
 
        Dim sqlQuestions As String = "SELECT questionID, questionType, questionText, questionImageFilename, courseID, " & _
            "questionStatus FROM dbo.trn_assessmentQuestions " & _
            "where courseID = " & courseID
 
        Dim dtStamp As Date = Now()
        Dim scnd As Integer = dtStamp.Second
        Dim sqlApd As String
 
        If scnd Mod 2 = 0 Then
            sqlApd = "DESC"
        Else
            sqlApd = "ASC"
        End If
 
        Dim sqlAnswers As String = "SELECT answerID, questionID, answerText, answerStatus, correct " & _
            "FROM dbo.trn_assessmentAnswers order by answerID " & sqlApd
 
        Dim da As New SqlDataAdapter(sqlQuestions, con)
        Dim ds As New DataSet()
 
        Try
            con.Open()
 
            da.Fill(ds, "Questions")
            da.SelectCommand.CommandText = sqlAnswers
            da.Fill(ds, "Answers")
 
            Dim relation As New DataRelation("questions", ds.Tables("Questions").Columns("questionID"), ds.Tables("Answers").Columns("questionID"))
 
            ds.Relations.Add(relation)
 
            Dim i As Integer = 10
            Dim x As Integer = 1
 
            'Markus
            Dim dummy As Integer = 1
 
            For Each row As DataRow In ds.Tables("Questions").Rows
                Dim lbl As Label = New Label()
 
                'Markus
                lbl.ID = "QID" & row("questionID").ToString
                lbl.Attributes("name") = dummy
 
                lbl.Style("margin-top") = i
                lbl.Style("margin-left") = "10px"
                lbl.Style("width") = "200px"
                lbl.SkinID = "question"
                lbl.Style("padding-top") = "20px"
                lbl.Style("padding-bottom") = "10px"
 
                Dim question As String = row("questionText").ToString
                lbl.Text = Convert.ToString(x) & ": " & question
                pnlAssessment.Controls.Add(lbl)
 
                'Markus
                dummy = dummy + 1
 
                If row("questiontype") = 37 Then
                    Dim img As Image = New Image
                    Dim test As String = Server.MapPath("~/App_Themes/jcb-v3/images/aqimages/" & row("questionImageFilename").ToString)
 
                    If Request.ServerVariables("LOCAL_ADDR") = "127.0.0.1" Then
                        img.ImageUrl = "http://localhost/jcbtraining/app_themes/jcb-v3/images/aqimages/" & row("questionImageFilename").ToString
                    Else
                        img.ImageUrl = "http://www.jcbtraining.com/app_themes/jcb-v3/images/" & row("questionImageFilename").ToString
                    End If
                    pnlAssessment.Controls.Add(img)
                End If
 
                Dim childRows As DataRow() = row.GetChildRows(relation)
 
                Dim rbl As CheckBoxList = New CheckBoxList()
                For Each childRow As DataRow In childRows
                    rbl.ID = row("questionid").ToString
                    Dim tPos As Integer = 60 * (i + 1)
                    rbl.Style("margin-top") = i + 20
                    rbl.Style("margin-left") = "50px"
                    rbl.Style("margin-bottom") = "20px"
                    rbl.Items.Add(childRow("answerText".ToString))
                Next
                rbl.SkinID = "CheckBoxList"
                rbl.Attributes("name") = "myname"
                pnlAssessment.Controls.Add(rbl)
 
                x = x + 1
            Next
 
        Catch ex As Exception
            System.Diagnostics.Debug.WriteLine("Error " & ex.Message & vbCrLf)
        Finally
            con.Close()
        End Try
    End Sub
 
    Protected Sub btnSubmitAnswers_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmitAnswers.Click
        endAssessment(Convert.ToInt32(Session("AssessmentTrackingID")), 1, 1)
 
        pnlAssessment.Visible = False
 
        Dim i As Integer = 0
 
        For Each c As Control In Me.Controls
            For Each c1 As Control In c.Controls
                If c1.ID = "form1" Then
                    For Each c2 As Control In c1.Controls
                        If c2.ID = "cphNew2ColMain" Then
                            For Each c3 As Control In c2.Controls
                                If c3.ID = "pnlAssessment" Then
                                    For Each c4 As Control In c3.Controls
                                        System.Diagnostics.Debug.WriteLine("Control ID =  " & c4.ID & vbCrLf)
                                        If c4.GetType.ToString.Equals("System.Web.UI.WebControls.Label") Then
                                            System.Diagnostics.Debug.WriteLine("Label ID =  " & c4.ID & vbCrLf)
                                        End If
 
                                        If c4.GetType.ToString.Equals("System.Web.UI.WebControls.CheckBoxList") Then
                                            System.Diagnostics.Debug.WriteLine("CheckBoxList ID: " & c4.ID & vbCrLf)
 
                                            Dim tempCBL As CheckBoxList = CType(c4, CheckBoxList)
                                            For Each li As ListItem In tempCBL.Items
                                                If li.Selected Then
                                                    System.Diagnostics.Debug.WriteLine("Answer Checked: " & li.Value & vbCrLf)
                                                    storeTestAnswer(c4.ID, li.Value)
                                                End If
                                            Next
                                        End If
                                    Next
                                End If
                            Next
                        End If
                    Next
                End If
            Next
        Next
 
        getResult(Convert.ToInt32(Session("AssessmentTrackingID")))
    End Sub
 
    Protected Sub endAssessment(ByVal trackingID As Integer, ByVal endCode As Integer, ByVal completed As Integer)
        Dim objAs As New assessments()
        Dim success As Boolean = objAs.endAssessment(Convert.ToInt32(Request.Cookies("userid").Value), completed, endCode, trackingID, _
                                                      Convert.ToInt32(Session("AssessmentTrackingID")))
    End Sub
 
    Protected Sub storeTestAnswer(ByVal questionID As Integer, ByVal answer As String)
        Dim con As New SqlConnection(ConnectionStrings("dev").ConnectionString)
        Dim cmd As New SqlCommand("sp_enterAssessmentAnswer", con)
        cmd.CommandType = CommandType.StoredProcedure
 
        Dim pAssessID As SqlParameter = cmd.Parameters.AddWithValue("@assessmentID", Convert.ToInt32(Request.Cookies("assessmenttrackingrecordid").Value))
        pAssessID.Direction = ParameterDirection.Input
 
        Dim pUserID As SqlParameter = cmd.Parameters.AddWithValue("@userid", Convert.ToInt32(Request.Cookies("userid").Value))
        pUserID.Direction = ParameterDirection.Input
 
        Dim pQuestionID As SqlParameter = cmd.Parameters.AddWithValue("@questionID", questionID)
        pQuestionID.Direction = ParameterDirection.Input
 
        Dim pScalarAnswer As SqlParameter = cmd.Parameters.AddWithValue("@scalarAnswer", answer)
        pScalarAnswer.Direction = ParameterDirection.Input
 
        Try
            con.Open()
            cmd.ExecuteNonQuery()
        Catch ex As Exception
            submitToTextFile(Convert.ToInt32(Request.Cookies("assessmenttrackingrecordid").Value), _
                             Convert.ToInt32(Request.Cookies("userid").Value), questionID, answer)
        Finally
            con.Close()
        End Try
    End Sub
 
    Protected Sub submitToTextFile(ByVal assID As Integer, ByVal uid As Integer, ByVal qid As Integer, ByVal answer As String)
        Dim filePath As String = Server.MapPath("~/secure/pca/assessbackup/" & Convert.ToString(uid) & "_" & Convert.ToString(assID) & ".txt")
 
        If File.Exists(filePath) Then
            Dim sr As StreamWriter
            sr = File.AppendText(filePath)
 
            sr.WriteLine(assID & " " & uid & " " & qid & " " & answer)
            sr.WriteLine("--------------------------------------------------")
            sr.Flush()
            sr.Close()
        Else
            Dim sr As StreamWriter = File.CreateText(filePath)
            sr.WriteLine("The assessment for user ID " & Convert.ToString(uid) & ", assessment ID " & Convert.ToString(assID) & ", could not be stored in the database, " & _
            "the results are saved here.")
            sr.WriteLine(" ")
            sr.Close()
        End If
    End Sub

Open in new window

0
Comment
Question by:G0ggy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 25

Expert Comment

by:apeter
ID: 21858399
You are statically checking / looking controls.  It will break when there is change in ur control structure. use recursive like below so it can traverse to any level / child nodes.

You can go through them recursively:

public static void ListControls(System.Web.UI.Control ctrl)
{
foreach(Control subCtrl in ctrl.Controls)
{
   //Look for the control type here and take necessary action else call the function again to do recursive
ListControls(subCtrl);
}
}
0
 
LVL 11

Accepted Solution

by:
G0ggy earned 0 total points
ID: 21863675
I could dance an absolute jig! I have fixed it, sorry apeter it wasn't your solution.

I moved the creation of the controls to the Page_InitComplete event of the page and changed my code to:

For Each ctrl As Control In pnlAssessment.Controls
            If TypeOf (ctrl) Is CheckBoxList Then
                System.Diagnostics.Debug.WriteLine("C Control ID =  " & ctrl.ID.ToString & vbCrLf)

                Dim tempCBL As CheckBoxList = CType(ctrl, CheckBoxList)

                For Each li As ListItem In tempCBL.Items
                    If li.Selected Then
                        System.Diagnostics.Debug.WriteLine("Answer Checked: " & li.Value & vbCrLf)
                        storeTestAnswer(ctrl.ID, li.Value)
                    End If
                Next
            End If
        Next

Sorry to go on, but I have worked on this problem for so long! I'm soooo happy etc...
0
 
LVL 25

Expert Comment

by:apeter
ID: 21864837
Its ok. It may not be recursive but "foreach" statement is from the code snippet  i guess...any way your problem is solved :)
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IntroductionWhile developing web applications, a single page might contain many regions and each region might contain many number of controls with the capability to perform  postback. Many times you might need to perform some action on an ASP.NET po…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…

615 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question