About Me

My photo
Hello, I'm a technology geek looking to upgrade my programming skills. These are some of the things I'm learning along my journey.

Saturday, July 28, 2012

Create a Basic Quiz Engine (part 4)


This is a continuation of "Create a Basic Quiz Engine (part3)".

Let's add some more functionality to this quiz engine.

Example:

Quiz Engine Requirements
The password is encrypted before inserting into the User Profile table.
The user is given choices if the user name or password do not match.




Add the pages, controls, files and databases necessary to complete the project.

    Example:

    -Splash Page
    --button to try again
    --button to add user
    --button to exit
    -Quiz Database
    --User Security Table
    ---user key
    ---user IV

Use the code from "Create a Basic Quiz Engine (part3)" to create a new project. Add a "UserSecurity" table to the Quiz database.

In this project I will be using Rijndael standard and symmetric encryption which uses only one key for simplicity to encrypt and decrypt. You can find more information on various encryption technologies here.


Create a new table to hold the encryption keys with 2 columns:
UserKey - (varbinary)
UserIV - (varbinary)

Add logic to load the UserKey and UserIV in the UserSecurity table.

Example:
private void SplashPage_Load(object sender, EventArgs e)
{
 if (!ReadUserSecurityTable() && CheckForEmptyUserProfileTable())
  {
   try
      {
       // Create a new instance of the RijndaelManaged 
       // class.  This generates a new key and initialization  
       // vector (IV). 
       using (RijndaelManaged myRijndael = new RijndaelManaged())
         {
          bytUserKey = myRijndael.Key;
          bytUserIV = myRijndael.IV;
          InsertKeyandIV();
         }
       }// end try
    catch (Exception ex)
     {
      Console.WriteLine("Error: {0}", ex.Message);
     }// end catch
                
  }// end if (ReadUserProfileTable)

 if (!ReadUserSecurityTable() && !CheckForEmptyUserProfileTable())
  {
   MessageBox.Show("Error!! - User Keys Detected Without Users in Database - Please Exit");
   txtPassword.Visible = false;
   lblPassword.Visible = false;
   txtUserName.Visible = false;
   lblUserName.Visible = false;
   lblHeading.Visible = false;
   btnEnter.Visible = false;
   btnExit.Visible = true;
  }

   ReadUserSecurityTable();

}// end private void SplashPage_Load


Create 3 additional text boxes on the Splash page and add logic to the buttons to try again, add user or exit.

private void btnExit_Click(object sender, EventArgs e)
{
  Application.Exit();
}

private void btnAddUser_Click(object sender, EventArgs e)
{
  conn.ConnectionString = @"Data Source=KEN-HP\SQLSERVER2008R2;Initial Catalog=quiz1;Integrated Security=True";
  strUserName = txtUserName.Text;
  strUserPassword = txtPassword.Text;
  ReadUserSecurityTable();
  bytUserPasswordReceived = EncryptStringToBytes(strUserPassword, bytUserKey, bytUserIV);

  try
  {
   conn.Open();
   string queryStmt = "INSERT INTO UserProfile(UserName, UserPassword) VALUES(@UserName, @UserPassword)";

   using (SqlCommand _cmd = new SqlCommand(queryStmt, conn))
   {
    _cmd.Parameters.Add("@UserName", SqlDbType.NVarChar, 100);
    _cmd.Parameters.Add("@UserPassword", SqlDbType.VarBinary, 100);
    _cmd.Parameters["@UserName"].Value = strUserName;
    _cmd.Parameters["@UserPassword"].Value = bytUserPasswordReceived;
    _cmd.ExecuteNonQuery();
   }

  }// end try

  catch (Exception ex)
   {
    MessageBox.Show("Failed to insert to UserProfile");
   }
   finally
   {
    conn.Close();
   }

   // read the Profile Table and go to Question Page
   ReadUserProfileTable();

}// end btnAddUser_Click

private void btnEnter_Click(object sender, EventArgs e)
 {
  strUserName = txtUserName.Text;
  strUserPasswordReceived = txtPassword.Text;
           
  ReadUserProfileTable();
      
  if (!bolMatch)
   {
    MessageBox.Show("The User Name and/or Passord Does Not Match" + "\n" + "Try Again, Add User or Exit");
    txtPassword.Text = "";
    txtUserName.Text = "";
    txtUserName.Focus();
    btnAddUser.Visible = true;
    btnExit.Visible = true;
    btnTryAgain.Visible = true;
    btnEnter.Visible = false;
   }
}// end btnEnter_Click



Click here for the project code. Just create a SQL Server database with test data, edit the connection string and run it.

Monday, July 23, 2012

Create a Basic Quiz Engine (part 3)

This is a continuation of "Create a Basic Quiz Engine (part2)".

Let's add some more functionality to this quiz engine.

Example:

Quiz Engine Requirements
User is greeted is required to log into the program before entering.
The user ID from the Splash page is passed to the Question page.
The quiz displays percentage correct.









Add the pages, controls, files and databases necessary to complete the project.

    Example:

    -Splash Page 
    --text box to enter user name
    --text box to enter user password
    -Question page
    --total percentage correct label
    -Quiz Database 
    --User Profile Table
    ---user id
    ---user name
    ---user password


Use the code from "Create a Basic Quiz Engine (part2)" to create a new project. Add a "UserProfile" table to the Quiz database.

Create a new table to hold the user profile with 3 columns:
user id
user name
user password

Create two text boxes on the Splash page and add logic to the button to check the user name and password before going on to the Question page.

Example:
if (strUserName.ToString() == txtUserName.Text && strUserPassword == txtPassword.Text)
  {
   bolMatch = true;
   intUserID = (int)reader[0];
   QuestionPage qp = new QuestionPage(intUserID);
   qp.Visible = true;
   this.Hide();
  }
if (!bolMatch)
  {
   MessageBox.Show("The User Name and/or Passord Does Not Match" + "\n" + "Try Again");
   txtPassword.Text = "";
   txtUserName.Text = "";
   txtUserName.Focus();
  }
Pass the User ID from the Splash page to the Question page for display.

Example:
//QuestionPage.cs
public QuestionPage(int _intUserID)
//SplashPage.cs
QuestionPage qp = new QuestionPage(intUserID);


Create a label and logic in the Question page to display the average user score.

Example:
dblAverageScore = (double)intTotalScore / QuestionRowList.Count;
                dblAverageScore = dblAverageScore * 100;
                lblAverageScore.Text = "Your average score is: " + (int)dblAverageScore + "%";
                lblAverageScore.Visible = true;



Click here for the project code. Just create a SQL Server database with test data, edit the connection string and run it.

Thursday, July 19, 2012

Create a Basic Quiz Engine (part 2)

This is a continuation of "Create a Basic Quiz Engine (part1)".

Start by creating some extra criteria for your new enhanced quiz engine.

Example:

Quiz Engine Requirements
User is greeted by splash page.
Quizzes are multiple choice. One question per screen.
User can see the results on the screen in a detailed grid.
Results are stored in a SQL Server Database.
The user can exit the program before the quiz is finished.




List the pages, controls, files and databases necessary to complete the project.

Example:

    Welcome Page
    Question Page
    SQL Server Database

    -Welcome Page
    --button to navigate to question page
    -Question page
    --question description label
    --results description label
    --total score label
    --3 radio buttons with 3 descriptions
    --GridView
    --submit button
    --exit button
    -Quiz Database
    --Quiz Table
    ---question id
    ---question description
    ---question answer1 ID
    ---question answer1 Description
    ---question answer2 ID
    ---question answer2 Description
    ---question answer3 ID
    ---question answer3 Description
    ---question correct answer ID
    --UserScore Table
    ---RowID
    ---UserID
    ---UserName
    ---QuestionDescription
    ---UserAnswerID
    ---UserAnswerDescription
    ---QuizCorrectQuestionID
    ---QuizCorrectQuestionDescription
    ---UserQuestionScore



Use the code from "Create a Basic Quiz Engine (part1)" to create a new project. Add a "UserScore" table to the Quiz database.

Create a new class for the new "UserScore" list.

Example:
    class UserScore
    {
        public int intRowID { get; set; }
        public int intUserID { get; set; }
        public string strUserName { get; set; }
        public string strQuestionDescription { get; set; }
        public int intUserAnswerID { get; set; }
        public string strUserAnswerDescription { get; set; }
        public int intQuizCorrectQuestionID { get; set; }
        public string strQuizCorrectDescription { get; set; }
        public int intUserQuestionScore { get; set; }
    }


Hard code the user name and ID for this version.

Example:
int intUserID = 1;
string strUserName = "harry";


Load the questions and uncheck the radio buttons.
Populate the radio buttons and description label with the first question.

Example:
public QuestionPage()
{
    InitializeComponent();
    ClearUserScoreTable();
    ReadQuestionTable();

    foreach (Question objQuestion in QuestionRowList)
    {
        if (objQuestion.intQuestionID == intTestQuestionNumber)
        {
            lblQuestion.Text = objQuestion.strQuestionDescription;
            strQuestionDescription = objQuestion.strQuestionDescription;
            radioButton1.Text = objQuestion.strAnswer1Description;
            radioButton2.Text = objQuestion.strAnswer2Description;
            radioButton3.Text = objQuestion.strAnswer3Description;
            intCorrectQuestionID = objQuestion.intCorrectAnswerID;
            strCorrectQuestionDescription = objQuestion.strCorrectAnswerDescription;

        }
    }// end foreach

    radioButton1.Checked = false;
    radioButton2.Checked = false;
    radioButton3.Checked = false;

}// end QuestionPage()



Click here for the project code. Just create a SQL Server database with test data, edit the connection string and run it.

Wednesday, July 4, 2012

Create a Basic Quiz Engine (part 1)

Start by creating some criteria for your new quiz engine.
Example:
Quiz Engine Requirements
User is greeted by splash page.
Quizzes are multiple choice. One question per screen.
User can see the results on the screen.



List the pages, controls, files and databases necessary to complete the project.
Example:

Welcome Page
Question Page
SQL Server Database

-Welcome Page
--button to navigate to question page
-Question page
--question description
--3 radio buttons with 3 descriptions
--submit button
-Quiz Database
--question id
--question description
--question answer1 ID
--question answer1 Description
--question answer2 ID
--question answer2 Description
--question answer3 ID
--question answer3 Description
--question correct answer ID
Create a new project in Visual C# and add new forms to the project. Create a new SQL Server database for your project and add some test data.

Create a class to hold the questions and answers from the database.

Example:
class Question
 {
     public int intQuestionID { get; set; }
     public string strQuestionDescription { get; set; }
     public int intAnswer1ID { get; set; }
     public string strAnswer1Description { get; set; }
     public int intAnswer2ID { get; set; }
     public string strAnswer2Description { get; set; }
     public int intAnswer3ID { get; set; }
     public string strAnswer3Description { get; set; }
     public int intCorrectAnswerID { get; set; }
     public string strCorrectAnswerDescription { get; set; }
 }
Start by adding code to the "Welcome Page". The button in the "Welcome Page" should open up a new "Question Page".

Example:
private void button1_Click(object sender, EventArgs e)
{
    QuestionPage qp = new QuestionPage();
    qp.Visible = true;
    this.Hide();
}
Once the "Welcome Page" logic is complete, add the logic for "Question Page". The labels that describe the radio button must be populated with the "question answer description" fields for the first row in the database as well as the "question description" for the upper label control. This is done by reading the first row in the database and adding the fields to an object in a list.

Example:
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();
            conn.ConnectionString = @"integrated security=SSPI;data source=KEN-HP\SQLSERVER2008R2;" +
                "persist security info=False;initial catalog=quiz1";
    try
    {
        conn.Open();
        // Insert code to process data.

        SqlCommand command = new SqlCommand(
            "SELECT * FROM Table_1;",
            conn);

        SqlDataReader reader = command.ExecuteReader();

        if (reader.HasRows)
        {
            while (reader.Read())
            {
                Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
                            reader.GetString(1));
                Question qr = new Question();
                qr.intQuestionID = (int)reader[0];
                qr.strQuestionDescription = (string)reader[1];
                qr.intAnswer1ID = (int)reader[2];
                qr.strAnswer1Description = (string)reader[3];
                qr.intAnswer2ID = (int)reader[4];
                qr.strAnswer2Description = (string)reader[5];
                qr.intAnswer3ID = (int)reader[6];
                qr.strAnswer3Description = (string)reader[7];
                qr.intCorrectAnswerID = (int)reader[8];
                QuestionRowList.Add(qr);
            }
        }// end if (reader.HasRows)
        else
        {
            Console.WriteLine("No rows found.");
        }
        reader.Close();

    }// end try

    catch (Exception ex)
    {
        MessageBox.Show("Failed to connect to data source");
    }
    finally
    {
        conn.Close();
    }

    foreach (Question objQuestion in QuestionRowList)
    {
        if (objQuestion.intQuestionID == intTestQuestionNumber)
        {
            lblQuestion.Text = objQuestion.strQuestionDescription;
            radioButton1.Text = objQuestion.strAnswer1Description;
            radioButton2.Text = objQuestion.strAnswer2Description;
            radioButton3.Text = objQuestion.strAnswer3Description;
        }
    }// end foreach
}// end QuestionPage()


Once the radio button is selected by the user, the code checks to determine which radio button is selected and gives it a value from 1 to 3. This value is checked against the list to determine the correct answer. In this case, I hard-coded "intTestQuestionNumber" to make this example easier to follow.

Example:
if (radioButton1.Checked)
{
  Console.WriteLine("radio button1 checked");
  intUserAnswer = 1;
}
if (radioButton2.Checked)
{
  Console.WriteLine("radio button2 checked");
  intUserAnswer = 2;
}
if (radioButton3.Checked)
{
  Console.WriteLine("radio button3 checked");
                intUserAnswer = 3;
}

foreach (Question objQuestion in QuestionRowList)
{
  if (objQuestion.intQuestionID == intTestQuestionNumber)
  {
    if (objQuestion.intCorrectAnswerID == intUserAnswer)
    {
       lblResult.Text = "Your answer is correct!";
       lblResult.Visible = true;
    }
    else
    {
       lblResult.Text = "Your answer is NOT correct.";
       lblResult.Visible = true;
    }
  }
}// end foreach

Click here for the project code. Just create a SQL Server database with test data, edit the connection string and run it.



Create a SQL Server Database in Visual C#

Create a new project in Visual C#. Select Windows Forms Application in the New Project dialog box and enter a project name. Click "OK".


In the "Database Explorer" right click on "Data Connections" and choose "Add Connection...".


Click on "Change..." and select "Microsoft SQL Database File(SqlClient)" in the "Add Connection" dialog box. Fill in a new database name in the text box below. Make sure "Use Windows Authentication" is selected and click "OK".


Click "Yes" in the popup window.

Your new SQL Server database should be visible in the "Database Explorer". Expand the selection by clicking on the triangle to the left of the new database file.


Right click on the "Tables" folder and select "Add New Table".


Fill in some test columns in the entry grid and click save.


Choose a table name and click "OK".


Expand the "Tables" folder by clicking on the triangle to the left and verify that the new table has been created.


Right click on the new table name and select "Show Table Data".


Enter some test data in each row.