Share via


Building a Content Rating System for Microsoft Content Management Server 2002

Introduction

Ever wanted to build a content rating system for your site? This article shows you how you can implement a content rating system for your Microsoft Content Management Server (MCMS) 2002 web site.

In this article, we will take a look at how to setup the database for rating entries, adding the ratings through code, and how to aggregate the information back to the audience in an informative and eye pleasing graphical view.

There are a number of ways that this can be accomplished. In my example, the rating system will be implemented as an ASP.NET user control that lives on your MCMS template. When a user views the page, they will be able to give a rating for the posting, view the average rating, the number of reviews, and a graphical representation (bar chart) of the ratings for that posting.

By the end of this article you will have created a user control that you can drop on any of your MCMS templates and will look similar to the following images:


Figure 1. The above image shows the "Rate Content" link in the upper right corner


Figure 2. View of the rating form after the user clicks on the "Rate Content" link.

In this article, we will look at the following

  1. Creating the database
  2. Creating the control
    1. Creating the interface for the rating system
    2. Creating the routines for the rating system
  3. Implementing the control
  4. Article conclusion
  5. Download the complete code

Let’s get started!

Creating the Database

The first thing we need to do is setup the database that will be used for tracking the ratings. Why a separate database? Why can we not just add this new table to the MCMS database? The answer to that is quite simple…it’s not recommended nor supported to house other tables within your MCMS database.

  1. Open SQL Server Enterprise Manager

  2. Create a new database called CMSRatingSystem

  3. Create a table called tblContentRating. This will keep track of the ratings.

  4. The table should have the following columns

    strGuid – The Guid for the posting
    lngRatingScore – The rating score for the posting
    dtiDateRated – Date/Time stamp for the rating given

    You may also use this script below to create your table:

    CREATE TABLE [dbo].[tblContentRating] (
    [strGuid] [char] (38) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [lngRatingScore] [decimal](19, 0) NOT NULL ,
    [dtiDateRated] [datetime] NOT NULL
    ) ON [PRIMARY]
    GO

Note: Another optional feature you might want to consider is a comments field so users can enter comments. Ensure you add a column for the comments if you want to track that as well.

Creating the control

In this section we will go over the features that we want to implement for this rating system and then tie them all together in a user control.

The first thing you need to ask yourself is “What do I want this to look like”? In my example, I want to ensure I have the following features:

  1. A link that says “Rate Content”

  2. When users click on that link, I want a form to appear without having to post back to the server.

  3. I want the form to not interfere with my design

  4. I want the control to have two parts, a section to rate the posting, and a section that generates the rating information about the posting.

  5. In the section that generates the rating information, I want to show the users the following:

    Posting name
    Average rating
    Number of reviews
    Graphical representation (bar chart) of the ratings for this posting
     

  6. The ability to encapsulate all the functionality without the use of images.

Now that I know what I want in my control, it’s time to write code!

Creating the Interface for the Rating System

  1. Open your MCMS application.

  2. Create a new user control called ContentRatingSystem.ascx

  3. At this point, you will need to decide how you want your user interface implemented. Based on my requirement mentioned above I will need to do the following:

    1. Add a HyperLink Control for the users to click to view/rate the posting data.
    2. Create a JavaScript function to toggle the visibility of the form.
    3. Create a form to rate the posting that contains 9 radio buttons and a submit button.
    4. Create 4 label controls (average rating, number of ratings, posting name, error message).
    5. Create 9 literal controls for the graphics (we will inject HTML inside the literal controls to make the bar charts appear like images).
  4. Here is the HTML code for my control (Again, you can modify the look and feel as much as you want at this point):

    <%@ Control Language="c#" AutoEventWireup="false" Codebehind="ContentRatingSystem.ascx.cs" Inherits="CMSApplication.UserControls.ContentRatingSystem" TargetSchema="https://schemas.microsoft.com/intellisense/ie5"%>
    <script type="text/javascript">
    function toggleRating()
    {
    if (document.all)
    {
    if(document.all.divRating.style.visibility == 'visible')
    {
    document.all.divRating.style.visibility = 'hidden';
    document.all.UCCMSRating_lnkRating.innerHTML="Rate Content";
    }
    else
    {
    document.all.divRating.style.visibility = 'visible';
    document.all.UCCMSRating_lnkRating.innerHTML="Click To Hide";
    }
    }
    }
    </script>
    <asp:hyperlink id="lnkRating" runat="server" ToolTip="Rate the content on this page">Rate Content</asp:hyperlink>
    <span id="divRating" style="LEFT: 490px; VISIBILITY: hidden; POSITION: absolute; TOP: 80px">
    <TABLE id="Table1" cellSpacing="0" cellPadding="4" width="400" bgColor="#f4f4f4" border="0"
    style="BORDER-RIGHT: #c0c0c0 1px dotted; PADDING-RIGHT: 4px; BORDER-TOP: #c0c0c0 1px dotted; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: #c0c0c0 1px dotted; PADDING-TOP: 1px; BORDER-BOTTOM: #c0c0c0 1px dotted; hidden: ">
    <TR>
    <TD vAlign="top" colSpan="1" rowSpan="1">
    <P><STRONG><FONT face="Verdana" size="2">How would you rate the quality of this content?</FONT></STRONG><BR>
    <BR>
    <TABLE id="Table2" cellSpacing="0" cellPadding="1" border="0">
    <TR>
    <TD></TD>
    <TD>
    <P align="center"><FONT face="Verdana" size="1">1</FONT></P>
    </TD>
    <TD>
    <P align="center"><FONT face="Verdana" size="1">2</FONT></P>
    </TD>
    <TD>
    <P align="center"><FONT face="Verdana" size="1">3</FONT></P>
    </TD>
    <TD>
    <P align="center"><FONT face="Verdana" size="1">4</FONT></P>
    </TD>
    <TD>
    <P align="center"><FONT face="Verdana" size="1">5</FONT></P>
    </TD>
    <TD>
    <P align="center"><FONT face="Verdana" size="1">6</FONT></P>
    </TD>
    <TD>
    <P align="center"><FONT face="Verdana" size="1">7</FONT></P>
    </TD>
    <TD>
    <P align="center"><FONT face="Verdana" size="1">8</FONT></P>
    </TD>
    <TD>
    <P align="center"><FONT face="Verdana" size="1">9</FONT></P>
    </TD>
    <TD></TD>
    <TD></TD>
    </TR>
    <TR>
    <TD><FONT face="Verdana" size="1">Poor</FONT></TD>
    <TD><INPUT type="radio" value="1" name="CMSRatingScale"></TD>
    <TD><INPUT type="radio" value="2" name="CMSRatingScale"></TD>
    <TD><INPUT type="radio" value="3" name="CMSRatingScale"></TD>
    <TD><INPUT type="radio" value="4" name="CMSRatingScale"></TD>
    <TD><INPUT type="radio" CHECKED value="5" name="CMSRatingScale"></TD>
    <TD><INPUT type="radio" value="6" name="CMSRatingScale"></TD>
    <TD><INPUT type="radio" value="7" name="CMSRatingScale"></TD>
    <TD><INPUT type="radio" value="8" name="CMSRatingScale"></TD>
    <TD><INPUT type="radio" value="9" name="CMSRatingScale"></TD>
    <TD><FONT face="Verdana" size="1">Outstanding</FONT></TD>
    <TD>
    <P>&nbsp;
    <asp:button id="cmdSubmit" style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 10px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; COLOR: #000000; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; FONT-FAMILY: Verdana; BACKGROUND-COLOR: #ebebeb"
    runat="server" Text="Submit"></asp:button></P>
    </TD>
    </TR>
    </TABLE>
    </P>
    <P>
    <HR width="100%" SIZE="1">
    <P></P>
    <P><asp:label id="lblPostingName" runat="server" Font-Names="Verdana" Font-Size="X-Small"></asp:label><BR>
    <asp:label id="lblAverageRating" runat="server" Font-Names="Verdana" Font-Size="X-Small"></asp:label><BR>
    <asp:label id="lblNumPeopleRated" runat="server" Font-Names="Verdana" Font-Size="X-Small"></asp:label><BR>
    <asp:label id="lblErrorMessage" runat="server" Font-Names="Verdana" Font-Size="X-Small" Visible="False"
    ForeColor="Red"></asp:label></P>
    <P><STRONG><FONT face="Verdana" color="#808080" size="1">The following is a graphical
    representation for the ratings</FONT></STRONG></P>
    <P>
    <TABLE id="Table3" cellSpacing="0" cellPadding="3" border="0">
    <TR vAlign="baseline">
    <TD vAlign="baseline" colSpan="1" rowSpan="1"><FONT color="#808080"><asp:literal id="lit1" runat="server"></asp:literal></FONT></TD>
    <TD><FONT color="#808080"><asp:literal id="lit2" runat="server"></asp:literal></FONT></TD>
    <TD><FONT color="#808080"><asp:literal id="lit3" runat="server"></asp:literal></FONT></TD>
    <TD><FONT color="#808080"><asp:literal id="lit4" runat="server"></asp:literal></FONT></TD>
    <TD><FONT color="#808080"><asp:literal id="lit5" runat="server"></asp:literal></FONT></TD>
    <TD><FONT color="#808080"><asp:literal id="lit6" runat="server"></asp:literal></FONT></TD>
    <TD><FONT color="#808080"><asp:literal id="lit7" runat="server"></asp:literal></FONT></TD>
    <TD><FONT color="#808080"><asp:literal id="lit8" runat="server"></asp:literal></FONT></TD>
    <TD><FONT color="#808080"><asp:literal id="lit9" runat="server"></asp:literal></FONT></TD>
    </TR>
    <TR>
    <TD><FONT face="Verdana" color="#808080" size="2">1</FONT></TD>
    <TD><FONT face="Verdana" color="#808080" size="2">2</FONT></TD>
    <TD><FONT face="Verdana" color="#808080" size="2">3</FONT></TD>
    <TD><FONT face="Verdana" color="#808080" size="2">4</FONT></TD>
    <TD><FONT face="Verdana" color="#808080" size="2">5</FONT></TD>
    <TD><FONT face="Verdana" color="#808080" size="2">6</FONT></TD>
    <TD><FONT face="Verdana" color="#808080" size="2">7</FONT></TD>
    <TD><FONT face="Verdana" color="#808080" size="2">8</FONT></TD>
    <TD><FONT face="Verdana" color="#808080" size="2">9</FONT></TD>
    </TR>
    </TABLE>
    </P>
    </TD>
    </TR>
    </TABLE>
    </span>

Creating the Routines for the Rating System

Now that we have our look and feel, its time to build in the functionality. Lets switch to code view and begin!

  1. Add the MCMS using directives

    using Microsoft.ContentManagement.Publishing;
    using Microsoft.ContentManagement.Common;
     

  2. Create a GenerateContentRatingInformation function. This function will be used to generate the statistics about the ratings for this posting.

    private void GenerateContentRatingGraph()
    {
    // Draw the rating graph for this posting
    lit1.Text = "<table bgcolor=#cedefa><tr><td height=" + GetScaleHeight(1) + " width=5></td></tr></table>";
    lit2.Text = "<table bgcolor=#cedefa><tr><td height=" + GetScaleHeight(2) + " width=5></td></tr></table>";
    lit3.Text = "<table bgcolor=#cedefa><tr><td height=" + GetScaleHeight(3) + " width=5></td></tr></table>";
    lit4.Text = "<table bgcolor=#cedefa><tr><td height=" + GetScaleHeight(4) + " width=5></td></tr></table>";
    lit5.Text = "<table bgcolor=#cedefa><tr><td height=" + GetScaleHeight(5) + " width=5></td></tr></table>";
    lit6.Text = "<table bgcolor=#cedefa><tr><td height=" + GetScaleHeight(6) + " width=5></td></tr></table>";
    lit7.Text = "<table bgcolor=#cedefa><tr><td height=" + GetScaleHeight(7) + " width=5></td></tr></table>";
    lit8.Text = "<table bgcolor=#cedefa><tr><td height=" + GetScaleHeight(8) + " width=5></td></tr></table>";
    lit9.Text = "<table bgcolor=#cedefa><tr><td height=" + GetScaleHeight(9) + " width=5></td></tr></table>";
    }
     

  3. Create an InsertContentRating function. This will be used to insert a new rating.

    private void InsertContentRating()
    {
    // SQL query to insert new content
    string sqlStmt = "INSERT INTO tblContentRating " +
    "(strGuid, lngRatingScore) " +
    "VALUES('" + Session["strGuid"].ToString() + "'," + Request.Form["CMSRatingScale"] + ")";

    SqlConnection conn = new SqlConnection("Data Source=server;Initial Catalog=CMSRatingSystem;User Id=sa;Password=pass;");

    // Insert the rating
    try
    {
    conn.Open();
    SqlCommand cmd = new SqlCommand(sqlStmt, conn);
    cmd.ExecuteNonQuery();
    }
    catch(Exception ex)
    {
    lblErrorMessage.Text = "There was an error submitting the rating for this page.<br><br>" + ex.ToString();
    lblErrorMessage.Visible = true;

    }
    finally
    {
    conn.Close();
    }
    }
     

  4. Create a GenerateContentRatingGraph function. This will be called to generate the graph for the ratings.

    private void GenerateContentRatingInformation()
    {
    // SQL query to get information for the form
    string sqlStmt = "SELECT AVG(lngRatingScore), COUNT(*) " +
    "FROM tblContentRating " +
    "WHERE strGuid = '" + Session["strGuid"].ToString() + "'";

    SqlConnection conn = new SqlConnection("Data Source=server;Initial Catalog=CMSRatingSystem;User Id=sa;Password=pass;");
    SqlCommand cmd = new SqlCommand(sqlStmt, conn);

    // Display the average rating, number rated, and call the rating graph function
    try
    {
    conn.Open();

    SqlDataReader dr = cmd.ExecuteReader();

    if(dr.HasRows)
    {
    while (dr.Read())
    {
    if((int)dr.GetValue(1) > 0)
    {
    lblAverageRating.Text = "<b>Average Rating:</b> " + Math.Round((decimal)dr.GetValue(0),2);
    lblNumPeopleRated.Text = "<b>Number of Reviews:</b> " + dr.GetValue(1);
    }
    else
    {
    lblAverageRating.Text = "There are not ratings for this content yet!";
    }
    }

    dr.Close();

    GenerateContentRatingGraph();

    }
    }
    catch(Exception ex)
    {
    lblErrorMessage.Text = "There was an error retrieving the content rating information for this posting.<br><br>" + ex.ToString();
    lblErrorMessage.Visible = true;
    }
    finally
    {
    conn.Close();
    }
    }
     

  5. Create a GetScaleHeight function. This is used to determine the bar chart height.

    private decimal GetScaleHeight(int strScaleNumber)
    {
    // SQL query to get the height of the graph for this rating/posting combination
    string sqlStmt = "SELECT CAST(COUNT(lngRatingScore) AS DEC) " +
    "/(SELECT CAST(COUNT(lngRatingScore) AS DEC) " +
    "FROM tblContentRating " +
    "WHERE strGuid = '" + Session["strGuid"].ToString() + "')*100 " +
    "FROM tblContentRating " +
    "WHERE lngRatingScore = " + strScaleNumber + " " +
    "AND strGuid = '" + Session["strGuid"].ToString() +"'";

    SqlConnection conn = new SqlConnection("Data Source=server;Initial Catalog=CMSRatingSystem;User Id=sa;Password=pass;");
    SqlCommand cmd = new SqlCommand(sqlStmt, conn);

    // Get the value (height) to return. Return 0 if nothing.
    try
    {
    conn.Open();

    SqlDataReader dr = cmd.ExecuteReader();

    if(dr.HasRows)
    {
    while (dr.Read())
    {
    return Math.Round((decimal)dr.GetValue(0),0);
    }

    dr.Close();
    }
    else
    {
    return 0;
    }
    }
    catch(Exception ex)
    {
    lblErrorMessage.Text = "There was an error retrieving the content rating information for this posting.<br><br>" + ex.ToString();
    lblErrorMessage.Visible = true;
    }
    finally
    {
    conn.Close();
    }
    return 0;
    }
     

  6. Add the following to the Page_Load event

    // Retrieve the current posting name
    Posting curPosting = CmsHttpContext.Current.Posting;
    lblPostingName.Text = "<b>Content:</b> " + curPosting.DisplayName.ToString();

    // Retrieve the Guid and store in session object
    string strGuid = curPosting.Guid.ToString();
    Session["strGuid"] = strGuid;

    // Generate the information in the rating form
    GenerateContentRatingInformation();

    // JavaScript to toggle the visiblity of the rating form
    lnkRating.Attributes["OnClick"] = "toggleRating();";
    lnkRating.NavigateUrl="javascript:void(0);";
     

  7. Add the following to the cmdSubmit_Click event

    // Insert the rating
    InsertContentRating();

    // Generate the information in the rating form
    GenerateContentRatingInformation();

  8. After you have added all your code, ensure that you build your project.
     

Implementing the control

The last thing to do will be to implement the control.

  1. Open an existing MCMS template for your MCMS application.
  2. Drag the ContentRatingSystem User Control on to your template file.
  3. Save this template.

Conclusion

In this article you have seen how to create a content rating system for MCMS 2002. You may have decided to implement this in a different fashion, but you know have the concepts to move forward. Here are some things that you may want to consider as you refine your own content rating system:

  1. Adding a comments box similar to the way MSDN built their content rating system.
  2. Storing the connection string in one universal location, such as the web.config or the session object.
  3. Using actual images to generate the graph, or take it a step further and generate a dynamic bar chart image using the System.Drawing namespace that resides within the .NET Framework.
  4. Using star images instead of a bar chart.
  5. Displaying the information before the user clicks on the link.
  6. Ensuring that each user can only rate the page once. You could use cookies to do this.

Complete Code

Download the complete code here.

This posting is provided "AS IS" with no warranties, and confers no rights.