As my first article on Code Project, I'd like to talk about a little proof of concept I created around AJAX/Atlas technologies. When I saw this screencast, I thought it could be easily used for a simple AJAX quiz system, so here I am :) The Code is really simple and there's no error management, but maybe later, I'll update this code to create a more complete solution.
To be able to use this code, you'll have to do the following:
- Install Atlas.
- Create an SQL database called AjaxQuiz and execute the SQL script which comes with the source code.
- Add a reference to the Atlas DLL (usually located in C:\Program Files\Microsoft ASP.NET\Atlas\v2.0.50727\Atlas).
- Modify the
AjaxQuiz connection string in web.config.
The AjaxQuiz database contains three tables: t_Questions, t_Answers, and t_UserAnswers. There's also a single Stored Procedure called by our Web Method to process the data:
CREATE PROCEDURE dbo.ProcessNextQuestion
@intQuestionID int = 0,
@intAnswerID int = 0,
@intUserID int = 0
IF @intQuestionID > 0 AND @intAnswerID > 0 AND @intUserID > 0
INSERT INTO t_UserAnswers(UserID, AnswerID, QuestionID)
VALUES(@intUserID, @intAnswerID, @intQuestionID)
SELECT TOP 1 QuestionID, QuestionText
WHERE QuestionID > @intQuestionID
As you can see, if the SQL input parameter isn't null, the Stored Procedure inserts results of the previous question in the database. Then, it returns the text and ID for the next question. As the
QuestionID is auto-incremented, the next question is always returned, but it supposes that IDs correspond to the desired question order.
There's only one web page in this small project: Default.aspx. First, I have to describe the
<atlas:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true">
<atlas:ScriptReference Path="AjaxQuiz.js" />
<atlas:ServiceReference Path="QuestionService.asmx" />
That's where Atlas is really nice: we just need to reference our JS client script and our Web Service, and Atlas will do the rest (the client code to consume the WS, etc.) In our JS code, we will also be able to create instances of classes defined in the server code. Atlas will do the correspondence for us.
<input id="btnStart" type="button" value="Start the Ajax Quiz !" onclick="Callback()" />
<div id="QuizForm" style="display: none;">
<div id="QuestionText"></div><br />
<input type="radio" id="YesAnswer" name="Answer" checked="checked" /> Yes
<input type="radio" id="NoAnswer" name="Answer" /> No
<input type="radio" id="DontKnowAnswer" name="Answer" /> ?<br /><br />
<input id="btnCallBack" type="button" value="Next" onclick="Callback()" />
<img id="imgUpdate" src="Images/spinner.gif" alt="Updating data" style="display: none;" />
<input id="QuestionID" type="hidden" value="0" />
<div id="EndForm" style="display: none;">
Thank you, this quiz is now finished !
Then, we add some HTML controls to create our form. First of all, there are three
DIVs: one that shows on startup, another for quiz questions, and a last one displayed when the quiz is finished. The main section,
QuizForm, contains three radio buttons for answers, a button to call our Web Service, and an image shown during AJAX calls.
The Web Service contains only one WebMethod,
public Question StoreAnswer(Question previousQuestion)
Question nextQuestion = null;
if (previousQuestion == null)
previousQuestion = new Question(0, "", 0);
using (SqlConnection cn = new SqlConnection(
SqlCommand cmd = new SqlCommand("dbo.ProcessNextQuestion", cn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter parm = new SqlParameter("@intQuestionID", SqlDbType.Int);
parm.Value = previousQuestion.QuestionID;
parm.Direction = ParameterDirection.Input;
SqlParameter parm2 = new SqlParameter("@intAnswerID", SqlDbType.Int);
parm2.Value = previousQuestion.AnswerID;
parm2.Direction = ParameterDirection.Input;
SqlParameter parm3 = new SqlParameter("@intUserID", SqlDbType.Int);
parm3.Value = userID;
parm3.Direction = ParameterDirection.Input;
using (SqlDataReader rd =
nextQuestion = new Question(rd.GetInt32(0), rd.GetString(1));
The WebMethod calls a stored procedure, then returns the next question as a
Question object. I made the thread sleep for one second, so that I can see the spinner image.
OnError functions aren't included but are present in the Zip file.
var questionID = document.getElementById('QuestionID');
var answer1 = document.getElementById('YesAnswer');
var answer2 = document.getElementById('NoAnswer');
var answer3 = document.getElementById('DontKnowAnswer');
var answerID = 0;
if(answer1.checked) answerID = 1;
if(answer2.checked) answerID = 2;
if(answer3.checked) answerID = 3;
var object = new Question();
object.QuestionID = questionID.value;
object.AnswerID = answerID;
QuestionService.StoreAnswer(object, OnComplete, OnTimeout, OnError);
var StartForm = document.getElementById('StartForm');
var QuizForm = document.getElementById('QuizForm');
var EndForm = document.getElementById('EndForm');
var questionID = document.getElementById('QuestionID');
var questionText = document.getElementById('QuestionText');
if(response != null)
StartForm.style.display = 'none';
EndForm.style.display = 'none';
QuizForm.style.display = 'block';
questionID.value = response.QuestionID;
questionText.innerHTML = response.QuestionText;
EndForm.style.display = 'block';
QuizForm.style.display = 'none';
And that's all! When the user clicks on the Start button, he sees the first question appear. No result is inserted in the database, because the input
Question object is null. Then, when he clicks on the Next button, results are stored in the database and our stored procedure sends the next question ... and so on until the Stored Procedure doesn't return anything. In that case, finally, the user sees the ending message.
OK, I know this is a quite simple article, but I think it can illustrate what you can do with Atlas and how easy it is. I hope my English isn't too bad too :)