- NET Overview
- The Survey Application
- Extending and Modifying the Survey Application
- Deploying the Survey Application
- Summary
I will do some things in the future to make the Survey application even more useful and flexible. I plan to do a couple of things to streamline the source code, too. I'm going to talk about my ideas here, and I might post them on the Web site in the future.
Streamlining the Code
I wrote this chapter so that it was easy to understand. Sometimes, I optimize code and sacrifice code readability as a result. I didn't want that to happen in the chapter examples, so as a result, some code could have been streamlined. The most obvious example in which I could have streamlined code is that for adding parameters to SqlCommand objects. Three lines of code are required to add a parameter along with its value, as shown here:
myCommand.Parameters.Add(New SqlParameter("@ID", SqlDbType.Int)) myCommand.Parameters("@ID").Direction = ParameterDirection.Input myCommand.Parameters("@ID").Value = nQuestionID
It would be good to create a helper method named AddParameter() that offers a single line of code to do what is done here in three lines of code. By helper method, I'm referring to a method that performs a small amount of functionality, not a full-blown sequence of functionality. We actually need two versions of the AddParameter() method for the Survey application, one for integers and one for strings. The two methods are shown below.
void AddParameter( SqlCommand myCommand, string strParamName, int nValue ) { myCommand.Parameters.Add( new SqlParameter( strParamName, SqlDbType.Int ) ); myCommand.Parameters[strParamName].Direction = ParameterDirection.Input; myCommand.Parameters[strParamName].Value = nValue; } void AddParameter( SqlCommand myCommand, string strParamName, string strValue, int nSize ) { myCommand.Parameters.Add( new SqlParameter( strParamName, SqlDbType.VarChar, nSize ) ); myCommand.Parameters[strParamName].Direction = ParameterDirection.Input; myCommand.Parameters[strParamName].Value = strValue; } Sub AddParameter(ByVal myCommand As SqlCommand,_ ByVal strParamName As string, ByVal nValue As Integer) myCommand.Parameters.Add(New SqlParameter(strParamName, _ SqlDbType.Int)) myCommand.Parameters(strParamName).Direction = _ ParameterDirection.Input myCommand.Parameters(strParamName).Value = nValue End Sub Sub AddParameter(ByVal myCommand As SqlCommand, _ ByVal strParamName As string, ByVal strValue as string, _ ByVal nSize As Integer ) myCommand.Parameters.Add(New SqlParameter(strParamName,_ SqlDbType.VarChar, nSize)) myCommand.Parameters(strParamName).Direction = _ ParameterDirection.Input myCommand.Parameters(strParamName).Value = strValue End Sub
C#
VB
Each of the above methods can be called from Survey application code, thus replacing three lines of code with one. Note one thing, though: These methods add only parameters that have an Input direction.
The following code,
myCommand.Parameters.Add(New SqlParameter("@Text", _ SqlDbType.VarChar, 254)) myCommand.Parameters("@Text").Direction = ParameterDirection.Input myCommand.Parameters("@Text").Value = Question.Text myCommand.Parameters.Add(New SqlParameter("@CategoryID", _ SqlDbType.Int)) myCommand.Parameters("@CategoryID").Direction = - ParameterDirection.Input myCommand.Parameters("@CategoryID").Value = _ CategoryList.SelectedIndex myCommand.Parameters.Add(New SqlParameter("@Enabled", - SqlDbType.Int)) myCommand.Parameters("@Enabled").Direction = _ ParameterDirection.Input myCommand.Parameters("@Enabled").Value = 0
can be replaced with these three lines:
AddParameter( myCommand, "@Text", Question.Text, 254 ) AddParameter( myCommand, _ "@CategoryID", CategoryList.SelectedIndex) AddParameter( myCommand, "@Enabled", 0 )
Using helper methods can reduce the amount of code in your applications. The AddParameter() method is a good example of how you can streamline your code with helper methods.
Here are the tradeoffs to consider when you are creating and using helper functions:
-
Does the helper method really simplify things? It can actually complicate matters if a lot of parameters must be passed.
-
Does the helper method make the code hard to read and thus hard to maintain? If the answer is Yes, then consider avoiding the use of helper functions that make code hard to read, especially if another developer will be maintaining the code.
-
Does the helper function reduce the overall amount of code without obfuscating the code's intent? If so, then the use of helper methods is desirable.
-
Does the helper function offer reusability so that the functionality can be maintained and bugs can be fixed in a single location? If so, then the user of helper methods is desirable.
Creating a GetSurveyInHTML() Method
You might want to create a method in the Web Service that takes a survey question and wraps it in HTML presentation code, by adding the appropriate HTML tags. If doing this would be helpful, then this section will get you started (although you most certainly will change the specifics of the presentation).
The method will start by calling the _GetSurveyData() method to retrieve the survey question and answer data. A single string will be returned to the client application that contains all of the HTML data.
The following method shown in Listing 3.20 creates HTML data that renders a survey question:
Listing 3.20 The GetSurveyInHTML() Method
C#
[WebMethod] public string GetSurveyInHTML( int nCategoryID, int nQuestionID, string strVoteURL ) { // Create the objects we'll need. SurveyData sd = _GetSurveyData( nCategoryID, nQuestionID ); SurveyResults sr = GetResults( sd.nQuestionID ); // Create the start of the Html data string. string strHTMLData = "<form name=\"Survey\" method=\"post\" action=\"" + strVoteURL + "?ID=4\">\r\n"; strHTMLData += "<script language=\"javascript\">\r\n"; strHTMLData += "\tfunction ShowResults()\r\n"; strHTMLData += "\t{\r\n"; strHTMLData += "\t\tSurveyResults.innerHTML = "; // Loop through each answer. for( int i=0; i<sd.Answers.Count; i++ ) { // Add the answer, the supporting Html, and the formatted number. strHTMLData += ( sd.Answers[i] + ": " + sr.dPercent[i].ToString( ".00" ) + "%"); if( i < sd.Answers.Count - 1 ) { strHTMLData += "<br>"; } else { strHTMLData += "\r\n"; } } // End this part of the Html. strHTMLData += "\t{\r\n"; strHTMLData += "</script>\r\n"; strHTMLData += ( "<P>" + sd.strQuestion + "<BR>\r\n" ); // Loop through each answer again. for( int i=0; i<sd.Answers.Count; i++ ) { // Create radio button Html code. strHTMLData += ( "<INPUT type=\"radio\" name=\"sr\" value=\"" + Convert.ToString( i ) + "\"> " + sd.Answers[i] + "<BR>\r\n" ); } // Add the Vote button. strHTMLData += "<INPUT type=\"submit\" value=\"Vote\"> " + "<INPUT type=\"button\" + " onclick=\"ShowResults()\" value=\"Results\"></P>\r\n"; strHTMLData += "<div id=\"SurveyResults\"></div>\r\n"; strHTMLData += "</form>\r\n"; return( strHTMLData ); }
VB
<WebMethod()> Public Function GetSurveyInHTML(ByVal nCategoryID _ As _ Integer, ByVal nQuestionID As Integer, _ ByVal strVoteURL As String) As String ' Create the objects we'll need. Dim sd As SurveyData = _GetSurveyData(nCategoryID, nQuestionID) Dim sr As SurveyResults = GetResults(sd.nQuestionID) ' Create the start of the Html data string. Dim strHTMLData As String = _ "<form name=Survey method=post action=" + strVoteURL + _ "?ID=4>" + vbCrLf strHTMLData += ("<script language=javascript>" + vbCrLf) strHTMLData += ("function ShowResults()" + vbCrLf) strHTMLData += (" {" + vbCrLf) strHTMLData += " SurveyResults.innerHTML = " ' Loop through each answer. Dim i As Integer For i = 0 To sd.Answers.Count – 1 ' Add the answer, the supporting Html, and the formatted number. strHTMLData += (sd.Answers(i) + ": " + _ sr.dPercent(i).ToString(".00") + "%") If i < sd.Answers.Count - 1 Then strHTMLData += "<br>" Else strHTMLData += vbCrLf End If Next ' End this part of the Html. strHTMLData += (" {" + vbCrLf) strHTMLData += ("</script>" + vbCrLf) strHTMLData += ("<P>" + sd.strQuestion + "<BR>" + vbCrLf) ' Loop through each answer again. For i = 0 To sd.Answers.Count – 1 ' Create radio button Html code. strHTMLData += ("<INPUT type=radio name=sr value=" + _ Convert.ToString(i) + "> " + _ sd.Answers(i) + "<BR>" + vbCrLf) Next ' Add the Vote button. strHTMLData += _ ("<INPUT type=submit value=Vote> <INPUT type=button" + _ " onclick=ShowResults() value=Results></P>" + vbCrLf) strHTMLData += ("<div id=SurveyResults></div>" + vbCrLf) strHTMLData += ("</form>" + vbCrLf) Return (strHTMLData) End Function
Adding a ResetResults() Method
At times, the results for a question need to be reset to zero. This reset might happen on a schedule, or as part of the administrative portion of the application. This section presents a method that can be added to the Web Service to do this, and it can be seen in Listing 3.21.
Listing 3.21 The ResetResults() Method
C#
[WebMethod] public string ResetResults( int nQuestionID ) { SqlConnection myConnection = new SqlConnection( Convert.ToString(Application["DBConnectionString"])); try { myConnection.Open(); string strSql = "update Answers set Cnt=0 where QuestionID=" + Convert.ToString( nQuestionID ); SqlCommand myCommand = new SqlCommand( strSql, myConnection ); myCommand.ExecuteNonQuery(); myConnection.Close(); } catch( Exception ex ) { if( myConnection.State == ConnectionState.Open ) { myConnection.Close(); } } }
VB
<WebMethod()> Public Function ResetResults(ByVal nQuestionID As _ Integer) Dim myConnection As New _ SqlConnection(Convert.ToString(Application("DBConnectionString"))) Try myConnection.Open() Dim strSql as string = _ "update Answers set Cnt=0 where QuestionID=" + _ Convert.ToString(nQuestionID) Dim myCommand As New SqlCommand(strSql, myConnection) myCommand.ExecuteNonQuery() myConnection.Close() Catch ex As Exception If myConnection.State = ConnectionState.Open Then myConnection.Close() End If End Try End Function