CIS Logo SVC Logo

   Computing & Information Systems
   Department

 

Schoology Facebook        Search CIS Site      Tutorials

A Web App with a Calculation Procedure



The Goals for this Example


One goal is to review items that you have already learned, such as how to use text boxes and buttons. Another is to see how to write a sub procedure in Visual Basic .NET. A few additional items are introduced as well, such as how program code can make an item on a form visible or invisible, how to read a stack trace to assist in handling a run-time error, and how to handle an exception in your code.

Creating the Example



What the App Should Do

  • We will create a web app that translates any reasonable binary number entered by the user into its decimal equivalent.
  • Note that the initial view of the web app shows an input box for a binary number, but does not show the output box for the corresponding decimal number (nor its label).
  • Once the Submit button is clicked, the output view of the web app shows all that was on the screen before plus the output information.

Familiar Items First

  • Begin as usual by creating a new project of type Visual Basic Projects, and having template ASP.NET Web Application. In the location box put in a reasonable location such as one of the following. (We will again use the same 2 examples throughout these directions.)
    • https://cis3.stvincent.edu/studentc/Bits
    • http://cis2.stvincent.edu/studentc/Bits
    This assumes that you want to name the project Bits. Adjust the rest of the location to suit your situation.
  • Then add items to the resulting new web form to produce something close to this image of the completed web form .
  • Note that this uses familiar items such as labels, text boxes, images, etc.
  • Although the images at the top of the form are not necessary, if you want to include them you can either copy them to your server from http://cis2.stvincent.edu/carlsond/svc.gif and http://cis2.stvincent.edu/carlsond/cis.jpg, or you can set the ImageURL in the Properties box for the 2 images to these URLs.
  • If you copy the images to your server, remember that you can use Solution Explorer to add them to your project. In MyComputer use Edit, Copy on an image file. Then go to the Solution Explorer, right click on your project icon and select Paste. You still need to adjust the ImageURL as mentioned above.
  • Format, Align was used to align the right edges of these 2 images.
  • Adjust the font size, foreground color, etc. for the labels to achieve the effect shown in the completed web form above (or something similar that is to your own liking).
  • Under Properties, change the IDs of the first and second text boxes to BinaryTextBox and DecimalTextBox respectively.
  • In the same way, change the ID of the label just above the second text box to DecimalLabel. We do this because we want an easy way to refer to this label in the code that we will write later. The IDs on the other labels do not matter as we will not reference them in our code.
  • Change the Visible property for the second text box and its label to false so that we will not initially see these 2 items.
  • Also change the ReadOnly property for this second text box to true so that the user cannot change what appears in it.
  • Change the properties for the button so that the background color is green, the foreground color is yellow, and the font is in italics. You can also experiment with the border style and color if you like. The app shown above uses Ridge and Yellow respectively for these items.
  • Save your work so far by using File, Save All.

The Click Handler

  • Double click the Convert button on your form. This will give you the outline of a procedure that will run whenever the user clicks on this button.
  • Add your code so that the section between the lines containing Sub and End Sub, the beginning and end of the procedure, are as follows:

Dim DecimalNumber As Int32
DecimalLabel.Visible = True
DecimalTextBox.Visible = True
BinaryToDecimal(BinaryTextBox.Text, DecimalNumber)
DecimalTextBox.Text = DecimalNumber.ToString

  • To see how this looks on screen, you can go to this picture of the code in the Visual Studio editor.
  • In the procedure there is one local variable, DecimalNumber, an integer in which we build up the answer.
  • Note how we make the text box and label visible: by assigning True into the Visible field of each item. (In a similar way, you can write code that makes the Visible field False.)
  • The BinaryToDecimal line is a procedure call, a call of a procedure that you will write below. Passed in as a parameter to this procedure is the text from the first text box. The second parameter is used to return the answer, the decimal version of the number in question.
  • This decimal number is then converted to a string which is placed into the text box that displays our answer.

Writing Your Own Procedure


Private Sub BinaryToDecimal(ByVal BinNum As String, ByRef DecNum As Int32)
    Dim k As Int32
    DecNum = 0
    For k = 0 To BinNum.Length - 1
        DecNum = 2 * DecNum
        If BinNum.Substring(k, 1) = "1" Then
            DecNum = DecNum + 1
        End If
    Next
End Sub

  • The algorithm used to convert from binary to decimal is known as Horner's method. Although this algorithm will not be explained here, more information can be found in a number of books on algorithms. We simply examine here some of the coding used.
  • Obviously the BinNum parameter is the string of 1's and 0's that we want to convert to decimal form and the DecNum parameter is the resulting decimal number as an integer (not a string).
  • The ByVal on the first parameter indicates that the value of the string used in the procedure call is copied into the BinNum parameter. Thus, the BinaryToDecimal procedure uses a copy of the original bit string. The second parameter is marked as ByRef to indicate that it is a reference parameter, one in which an answer can be returned.
  • There is an integer local variable k which is used as a loop control variable.
  • The second parameter, the one that will hold the answer, is initialized to 0.
  • The For..Next loop takes us through the bits in the input string one by one, from left to right.
  • Notice how it looks up the Length of the string.
  • Each time around the loop, the value of DecNum is multiplied by 2 and stored back into DecNum.
  • To look at the current bit in the string, the substring starting at index k and having length 1 is examined. This yields a string that holds a single character, which is then compared to a string containing just 1.
  • If a match for a 1 is found, DecNum has the number 1 added to it.
  • Note that you can create procedures of your own whenever you have useful chunks of code to package up.

Build Your App

  • Click on the Save All button in Visual Studio or use File, Save All.
  • Then use Build, Build Bits (or whatever you named your application).
  • If the build succeeded, the Output window will give you a message to that effect.
  • If not, fix any problems.

Testing and Debugging The App

Finding Errors

  • Look at your app in a browser by going to the appropriate URL. For example, the URL might be something like one of the following:
    • http://cis3.stvincent.edu/studentc/Bits/WebForm1.aspx
    • http://cis2.stvincent.edu/studentc/Bits/WebForm1.aspx
  • Put a binary number into the first text box and click the Convert button to see if your app works correctly. For example, the input of 1101 should produce 13.
  • If the app does not produce the desired results, check your code carefully to see that it matches what was given above.
  • If your app works well for small numbers, try larger ones.
  • This picture with a large input number shows everything working fine.
  • However, by making the input a little larger yet, we get a runtime error shown in the browser.
  • Even worse, the error message does not tell you what is wrong, though it does tell you how to get more information.
  • The solution, as the error screen suggests, is to double click the Web.config file in Solution Explorer and edit the line that says <customErrors mode="RemoteOnly" /> so that it instead reads as <customErrors mode="Off" />
  • Save everything, rebuild your application, and refresh the page in your browser. Enter long binary numbers until you get one long enough to give you a run-time error. You should now get a more helpful error message.
  • This error message clearly tells you that your code had an unhandled exception for overflow on some arithmetic operation. Essentially some number became too big.
  • Note that what you are seeing is called a stack trace, showing what line of code called what procedure, which called what other procedure, and so on when the error occurred.
  • If you scroll to the right to see the right end of the error message in the stack trace, you see that the exception happened on line 52 of your code.
  • Now you know what happened and where it happened.
  • Unfortunately, there is no easy way to fix the problem so that the application can handle a binary number of any length. Sooner or later we will overflow any number variable.
  • However, we can adjust our code so that it handles the overflow situation more gracefully, as the next section explains.
  • When finished with debugging, undo all of your changes to Web.config, save everything, and rebuild your app. This will leave your app in a more secure state. If a runtime error crops up later, you don't want everyone on the Internet to be able to read the detailed error messages.

Handling an Exception

  • Start by adding a red error label to your form as shown in this picture.
  • Have the text of the label read "Overflow error: the binary number was too large to handle."
  • Set the ID of this label to ErrorLabel so that we can easily refer to it later in our code.
  • Change the font of the label to Medium, the foreground color to Red, and make the Visible property False. We don't want this error label to appear unless an overflow error occurs.
  • Then go to your corresponding code file and change it as shown in this view of Visual Studio.
  • Here is the complete section of code after the changes:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ 
    Handles Button1.Click
	
    Dim DecimalNumber As Int32
    DecimalLabel.Visible = True
    DecimalTextBox.Visible = True
    ErrorLabel.Visible = False
    BinaryToDecimal(BinaryTextBox.Text, DecimalNumber)
    DecimalTextBox.Text = DecimalNumber.ToString
End Sub

' Uses Horner's method to convert the binary number contained in the string
' BinNum to the decimal equivalent, DecNum.
Private Sub BinaryToDecimal(ByVal BinNum As String, ByRef DecNum As Int32)
    Dim k As Int32
    DecNum = 0
    Try
        For k = 0 To BinNum.Length - 1
            DecNum = 2 * DecNum
            If BinNum.Substring(k, 1) = "1" Then
                DecNum = DecNum + 1
            End If
        Next
    Catch exception As OverflowException
        DecNum = 0
        ErrorLabel.Visible = True
    End Try
End Sub

  • Note that the Button1_Click procedure sets the Visible property of the above label to false. This is to guarantee that the error label starts as initially invisible when the click handler runs. Even though the Visible property of the label on the form is False, the label could be made visible later by an overflow error. If the user changes the input and clicks on the Convert button, the error label should go away (assuming that the input is now short enough). This line of code makes the error label go away in this situation.
  • In the BinaryToDecimal function, a Try...Catch..End Try construct has been added around the section of code that does the arithmetic. If an overflow exception is caught, the DecNum answer is set to 0 and the error label is made visible.
  • Save all of your files, build the project, and then try it in a browser. Make sure that the error label appears for really long binary numbers but not for shorter ones.

Input Validation

  • You might think that we are done now. However, we should also check other types of bad input.
  • For example, try typing 1 1 (with a space between the two 1's) into the text box for the binary number.
  • What answer did you get? Yes, indeed, 5. Surely 11 is the binary for 3, not 5. However, the space got interpreted as a zero because of the way we checked for single character substrings containing 1 in our conversion code above.
  • What other bad input could we give? Try something like 1A1.
  • This also gives 5 as the answer, though it is pretty meaningless.
  • You might also try an empty string in that binary number text box.
  • Sure, it converts this to 0. This is somewhat reasonable, though there is really no input number. We might want to force the user to enter something into the input box.
  • Obviously, we need a way to validate the user input so as to ensure that only reasonable binary numbers are entered into this text box. We might also want to ensure that the input box is not empty.
  • Happily, Visual Studio provides various types of validators to handle this type of thing.

Using a Regular Expression Validator

  • A regular expression validator can be used to verify that the data in our input text box fits a certain pattern. In this case the pattern is all 1's and 0's.
  • Drag a regular expression validator from the Toolbox onto your form, just to the right of the text box for the binary number.
  • Change the ErrorMessage property for this validator to "Error: use only 0's and 1's".
  • Change the font size to Medium.
  • Click in the ControlToValidate field and select BinaryTextBox from the drop down list. This is how you specify which text box this validator will check.
  • The only other property that we need to supply is the ValidationExpression. The way to write any number of 0's and 1's is [01]* using what is called a regular expression.
  • The regular expression can be typed into the ValidationExpression field in Properties or you can click on the ... button to see sample regular expressions for zip codes, phone numbers, etc. The dialog box brought up by this button also lets you type in your own regular expression in the bottom text box. Be careful not to enter any spaces as part of your regular expression as this will cause it to not work correctly.
  • You can find more information about regular expressions by using Visual Studio's help system. Click on Help, Search. Then type "regular expression" into the "Look for" box. Although some of the matches will not be helpful, look for ones that refer to Visual Basic or .NET itself. In fact, you can limit the search results by specifying Visual Basic in the "Filtered by" box.
  • Save your work, build the project, and then try it out in a browser.
  • Now if you enter 1A1 or other bad data as input, the validator's error message should appear, but legitimate binary numbers should work fine.

Using a Required Field Validator

  • Drag a RequiredFieldValidator from the Toolbox to your form. Place it just above the regular expression validator.
  • Change the ErrorMessage property for this validator to "Error: you must supply input."
  • Change the font size to Medium.
  • Change the ControlToValidate field to BinaryTextBox. This tells the validator to be sure that there is data in this text box.
  • Here is a picture of what we have at this point.
  • Save your work, build the project, and try it out in your browser.
  • Verify that the new error message appears if you leave the binary number box empty when you click the Convert button.

Alternate Design

Postback or Not Postback?

  • It is sometimes worthwhile to look at alternate ways to design a program solution.
  • In this case, instead of using a click handler we could have a section of code to handle what is called a postback.
  • A postback happens when a user submits data. This will happen automatically when the user clicks on a submit button unless there is a click handler that does something else.
  • When the web page is initially loaded the PostBack property is False.
  • After a postback, the PostBack property becomes True.
  • Thus we can use the PostBack property in our app to decide whether or not to calculate the decimal equivalent of a binary number.
  • Here is a picture of the revised code, which is also shown below:

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)  _
    Handles MyBase.Load
	
    'Put user code to initialize the page here
    DecimalLabel.Visible = True
    DecimalTextBox.Visible = True
    ErrorLabel.Visible = False
    If IsPostBack Then
        Dim DecimalNumber As Int32
        BinaryToDecimal(BinaryTextBox.Text, DecimalNumber)
        DecimalTextBox.Text = DecimalNumber.ToString
    End If
End Sub

' Uses Horner's method to convert the binary number contained in the string
' BinNum to the decimal equivalent, DecNum.
Private Sub BinaryToDecimal(ByVal BinNum As String, ByRef DecNum As Int32)
    Dim k As Int32
    DecNum = 0
    Try
        For k = 0 To BinNum.Length - 1
            DecNum = 2 * DecNum
            If BinNum.Substring(k, 1) = "1" Then
                DecNum = DecNum + 1
            End If
        Next
    Catch exception As OverflowException
        DecNum = 0
        ErrorLabel.Visible = True
    End Try
End Sub

  • Note that the BinaryToDecimal procedure is unchanged, but the click handler procedure is now gone.
  • Instead we have the Page_Load procedure take over its job.
  • In all cases, whether we have a postback or not, Page_Load sets the various controls to be visible or not as desired.
  • If we have a postback, Page_Load also calls upon BinaryToDecimal to figure out the decimal equivalent to the given binary number and then displays the answer in the appropriate text box.
  • If you want to try this coding alternative, you can either change your existing project's code or you can use Project, Copy Project to create a new copy of your project. Then open the copy and change the code in it.
  • After changing the code, save your work, build the project, and try the revised app in a browser.
  • It should behave in the same way as the previous version of this project.

Back to the main page for ASP .NET Web Apps



Author: Br. David Carlson
Last updated: October 08, 2008
Disclaimer