I just like to make things complicated…

When I started out to build a voting control, I drew up a set of requirements that led to a 5+ table system… some form of UI for creating/editing polls… plus the control itself. Then, when I had SQL running behind my web site, I wanted something up fast…. so I just grabbed a simple voting control from www.asp.net (by Rob Howard). The simplicity of this control (and its database structure) is a big plus, especially for me … it is a great place to start to play around with ASP.NET.

It is nice enough, but it doesn’t do what I need, so it is time to go back to my original design and build my own code instead of just messing around with Rob’s.

My set of requirements, documented in the tried and true UBL (universal bulleted list) format… which isn’t approved by Rational, or even by me, for use on real projects but works fairly well when I am the designer/user/developer/tester …

I need a polling system that allows me to

  • Display different polls on different areas of my site,
  • Specify dates for a poll to appear in different locations (without touching any of my actual site pages)
  • Allow the user to view results without voting, and then to be able to go back and vote if they wish to
  • Allow reporting of poll results, with full details (text displayed, etc..), even after the poll has ceased to be displayed
  • Track votes by date, so that votes can be summed across all time or for a specific date range
  • Track the site location from which the vote was submitted, so that response rate and actual results can be compared by location
I think that is about it for requirements… noting that I didn’t specify anything about how polls are created, controlled, edited, scheduled… I am a strong believer in incremental development so I can build the first poll or two manually while I finish that side of the system… and now I’m back at my 5 or so tables 🙂

There are still changes to make to this design, I want to be able to control the order of Options in the poll, for example… but I think I have enough to start building a proof-of-concept control…

(Listening To: Nautical Disaster [The Tragically Hip / Day for Night])

Comments (14)

  1. Why are you mixing uniqueidentifier primary keys with int primary keys?

    I would suggest using uniqueidentifiers for all tables you would use in editing/creating of poll. This way you could use a dataset, persist it between postbacks, create all identifiers without touching SQL Server, and then save all together after arbitrary number of user actions into DB, without generating a lot of temporary records. I’m always using this scenario when I have to provide user a way to define hierarchical data. It is much harder with ints.

  2. Michal, while I understand the point… I just use reverse incrementing id’s locally (-1, -2, -3, etc..) and it works fine… (child records just use the negative # as a Foreign Key and it is all updated when you update the parent records) the goal of using ints for those tables was to simplify the properties that a web editor (non-technical) will have to set on the control. Location=3 is much simpler than using a GUID that they will have to look up everytime they need to use it. I did use a GUID for the votes themselves but those should never be edited offline and I wanted to remove any issue of ‘how many votes will we get?’ if you consider that the system could run for decades on a busy site like MSDN… with multiple polls, etc…

  3. Just a thought… you might want to add a "DisplayOrder" field in the [PollOptions] table to allow you to control the order in which options appear in the list.

  4. Ok, I understand. That’s a nice trick I haven’t heard of. Have to check this out soon 🙂

  5. What’s the point in reverse incrementing id’s locally? Is it because you set the column in your datatable to not-nullable or is there any other reason?

    With GUIDS, you create those because you might want to reference them in other tables before persisting into the database. But there’s no point to this, from the way I see it, in your -1, -2 scenario…

  6. Dennis, the reason is exactly the same as for GUIDs… you create a new "Poll", set its ID to -1.. then you can go ahead and create 3 new PollOptions, with a PollID of -1, before ever submitting the original "Poll" back to the database. When you do finally update, you update the Poll table first, ADO.NET automatically cascades the update from -1 to 3432 (or whatever it is) to the PollOption table and then when you update it to the database, the PollID fields are set correctly.

  7. Oh, cascading updates within your DataSet. Didn’t know this, but definitly something I should know and should use.

    Another thing is, I’m trying to get into SOA right now and I’m using datasets to communicate between services. But that’s not really cool, if other platforms want to connect to my services. I’ll have to think about this one! 🙂

  8. Oh, to add to the list:

    – Blocking ip address after voting

    – Setting a cookie when voted

    The first is a problem for companies that have a lot of employees and all of them have the same ip on the internet. The second is for people carrying their laptop around and trying to vote on many different locations.

    The ip blocking might be a setting to be turned on and off.

    A good example is the following url where you need both methods to block people from voting twice: http://www.bild.t-online.de/BTO/sport/em2004/aktuell/06/16/voting__spielernoten/voting__spielernoten__deutschland.html

    Aha, it seems they took the page down.

    In Europe, the European Championship 2004 is going on. Two of the biggest rivals are my country, The Netherlands and Germany. A newspaper, Bild, was having a poll with who was becoming the winner of EK2004. An extremely popular Dutch blogsite made a post about the poll and lots and lots of people voted multiple times (even with scripts) for our country. So it looked like the Germans were voting for The Netherlands to be the winner. Quite funny! 😉

  9. Hmmm, I’m looking some more at your data model.

    Why the connection between vote and location? Isn’t the location connected to poll and not to vote?

    And I presume you set the ID in the location table in your .aspx (or .ascx) page. Then the developer of the site would have to take care he wouldn’t use one location twice. Or maybe that’s exactly what someone wants! 🙂

    Maybe we want another table, linked to location. In the new table we’d have a pagename where we could have "default.aspx" or "whatever.ascx". In it we would import the poll.ascx and the poll would check it’s owner or something and look it up in our new table. That way we could have a poll on different locations or something. I’m probably making some mistake here, but I’m just typing this fast before I go home…

    See yah! 😉