Blog Post

Building a PASS Voting Solution – Part 6

,

Today we’ll try to finish up by looking at a couple of the semi-interesting parts of the code in this one page application. We’ll start with the page load event. On the first run of the page (not postback) I’m grabbing the two keys I need if they exist and calling the MyBallot.Validate method (show you that next). From there I show some various bits of text and load the choices if appropriate, and then move on to deciding what to show them based on what we know.

‘only do on first page load

If Not Page.IsPostBack Then

    Try

        ‘try to load from query string

        MyBallot.BallotID = New Guid(Request.QueryString(“BallotID”))

        MyBallot.VoterID = New Guid(Request.QueryString(“VoterID”))

    Catch ex As Exception

    End Try

    MyBallot.Validate()

    ‘load the list if all is good

    If MyBallot.EligibleToVote And MyBallot.HasVoted = False Then

        MyBallot.LoadListBox(lstAvailable)

    End If

    ’set this regardless

    lblBallotTitle.Text = Me.MyBallot.Title

    lblBallotDescription.Text = Me.MyBallot.Description

    lblBallotItem.Text = MyBallot.Title

    lblMin.Text = MyBallot.MinSelection.ToString

    lblMax.Text = MyBallot.MaxSelection.ToString

    lblClosing.Text = MyBallot.ClosingDate.tostring

End If

‘various cases, all mutually exclusive

pnlVote.Visible = False

If MyBallot.EligibleToVote And MyBallot.HasVoted = False Then

    pnlVote.Visible = True

ElseIf MyBallot.HasVoted = True Then

    ShowMessage(“You have already completed your vote in this ballot.”, displaymessage.IconToDisplay.InformationIcon)

ElseIf MyBallot.BallotID = Guid.Empty Then

    ShowMessage(“To vote on a ballot you must provide the ballotid in the URL – contact PASS HQ for assistance”, displaymessage.IconToDisplay.InformationIcon)

Else

    pnlLookup.Visible = True

End If

Validate is where we call the proc GetBallotDetails, which you may recall returns both output parameters and a result set.

‘remove any old items

Me.BallotDetails.Clear()

Me.EligibleToVote = False

Me.Title = “Unknown”

Me.Description = “”

Me.MinSelection = 1

Me.MaxSelection = 1

Me.HasVoted = False

Dim dr As SqlDataReader

Using cmd As New SqlCommand()

    With cmd

        .Connection = OpenDBConnection()

        .CommandType = CommandType.StoredProcedure

        .CommandText = “Voting.GetBallotDetails”

        .Parameters.Add(New SqlParameter(“@BallotID”, DbType.Guid))

        .Parameters(“@BallotID”).Value = ballotID

        .Parameters.Add(New SqlParameter(“@VoterID”, DbType.Guid))

        .Parameters(“@VoterID”).Value = VoterID

        .Parameters.Add(New SqlParameter(“@IsEligibleToVote”, DbType:=SqlDbType.Bit))

        .Parameters(“@IsEligibleToVote”).Direction = ParameterDirection.Output

        .Parameters.Add(New SqlParameter(“@HasVoted”, DbType:=SqlDbType.Bit))

        .Parameters(“@HasVoted”).Direction = ParameterDirection.Output

        dr = .ExecuteReader

        Do While dr.Read

            ‘just assign these each time, shouldn’t change

            Me.Title = dr!ItemTitle

            Me.MinSelection = dr!MinSelection

            Me.MaxSelection = dr!maxSelection

            Me.Description = dr!Description

            Me.ClosingDate = dr!ClosingDate

            ‘next we add the details

            Dim oDetail As New BallotDetail() With {.BallotDetailID = dr!BallotDetailID, .Title = dr!DetailTitle}

            Me.BallotDetails.Add(oDetail)

        Loop

        dr.Close()

        HasVoted = cmd.Parameters(“@HasVoted”).Value

        EligibleToVote = cmd.Parameters(“@IsEligibleToVote”).Value

        dr = Nothing

    End With

End Using

Here is the code called when they finally vote. We check our local state to see if they have voted, and then we’ll check again within the proc to make sure! ExecuteProc is a helper method that handles calling a proc when it just takes parameters.

If Me.EligibleToVote = False Then

          Throw New Exception(“We have not identified you as an eligible voter for this ballot.”)

      ElseIf Me.HasVoted = True Then

          Throw New Exception(“You have already cast your vote for this ballot.”)

      End If

      ‘trim leading comma

      If SelectedDetails.Substring(0, 1) = “,” Then

          SelectedDetails = SelectedDetails.Substring(1, SelectedDetails.Length – 1)

      End If

      Dim Params(0 To 2) As SqlParameter

      Params(0) = VarcharParam(“@Details”, 8000, SelectedDetails, False)

      Params(1) = New SqlParameter(“@BallotID”, SqlDbType.UniqueIdentifier)

      Params(1).Value = BallotID

      Params(2) = New SqlParameter(“@VoterID”, SqlDbType.UniqueIdentifier)

      Params(2).Value = VoterID

      ExecuteProc(“Voting.CastVote”, Params)

      Me.HasVoted = True

There’s not much else that is interesting. It’s set up with a master page containing the logo, and the main page is a content page. I’m storing a Ballot object in session and it’s also set up to be accessible as a property of the page, making it easy to reference as a strongly typed object.

I came in right at 10 hours. Lost a little time thinking through how to handle multiple items on each ballot, couldn’t see a way to do that without adding a lot more complexity to the UI. It still needs some testing by someone other than me, and it’s a project where I think unit tests would be appropriate, lots of different cases that could be verified (eligible, not eligible, has/not voted, etc), but I think we can do most of that with UI testing that will be needed anyway.

By the time you read this I’ll have sent the bits off to HQ for install and testing. We’ll try it on a few board votes, and we may send out a test vote in the Connector too.

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating