Star rating system in ASP.NET MVC

Sheonarayan
Posted by in ASP.NET MVC category on for Advance level | Points: 250 | Views : 41862 red flag

In this article, we shall learn how to develop a star rating system in ASP.NET MVC. This article contains project source code with database structure as well.

Introduction

Rating of a post or thread or an article is a very common feature in any website. There might be few rating system projects available that are based on ajax and I feel little complicated to implement.

In this article, we will try to look into how to create a very simple yet awesome star rating system that is implemented using HTML, CSS, JavaScript, jQuery, ASP.NET MVC and SQL Server database table.

The complete Star Rating System Project source code is available at GitHub.


Star Rating system in ASP.NET MVC

Database table structure
In order to demonstrate this, let's first create sample database tables used for this project. Below is the table structure of the database tables. 

  1. Articles - this table stores the post details
  2. ArticlesComments - this table stores the comment details along with rating given for a particular post (ArticleId column stores the AutoId value of a particular Article post)




ASP.NET Project structure

The project structure of the rating system is below and that very simple. We have create
  1. Models for Articles table and ArticlesComments table in the Models folder
  2. Controllers for both the models
  3. Views have been created automatically while scaffolding the controller.


The important files where we have changed the major codes are
  1. /Controllers/ArticlesController
  2. /Views/Articles/Details.cshtml
  3. /Views/Shared/_CommentBox.cshtml (added)
  4. /Content/site.css
Remaining files have almost none or very minor change after scaffolding. 

Assuming that you have basic knowledge of ASP.NET MVC, I am directly jumping to /Views/Articles/Details.cshtml file where we are showing the posts and comment box that allows a visitor to rate the post.

Star rating system controller action method - /Controllers/ArticlesController.cs
In this action method, we get the Article post based on the id value passed. After that we get all the comments stored into 'ArticlesComments' table for this particular article post based on 'ArticleId' and then gets the sum of total rating (ratingSum) and then the number of rating (ratingCount). All these values are stored into ViewBag that will be ultimately retrieved on the Details view page.

        // GET: Articles/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Article article = db.Articles.Find(id);
            if (article == null)
            {
                return HttpNotFound();
            }
            ViewBag.ArticleId = id.Value;

            var comments = db.ArticlesComments.Where(d => d.ArticleId.Equals(id.Value)).ToList();
            ViewBag.Comments = comments;

            var ratings = db.ArticlesComments.Where(d => d.ArticleId.Equals(id.Value)).ToList();
            if (ratings.Count() > 0)
            {
                var ratingSum = ratings.Sum(d => d.Rating.Value);
                ViewBag.RatingSum = ratingSum;
                var ratingCount = ratings.Count();
                ViewBag.RatingCount = ratingCount;
            }
            else
            {
                ViewBag.RatingSum = 0;
                ViewBag.RatingCount = 0;
            }

            return View(article);
        }
Before we go to the view, let's see the magic .css class that highlights the star ratings

Star rating system .css class - /Content/site.css
There are two version of star css (image is in the source code on GitHub)
  1. starFade & starGlow - simply shows the faded (not rated) and glowing star (rated). Used while rating so that mouse pointer icon is shown.
  2. starFadeN & starGlowN - same as above however this doesn't show the mouse pointer icon but shows simply the star icon. Used to display the rating.

.commentBox {
    background-color:#efefef;
    padding:10px;
    border-radius:10px;
}

.starFade{
    background-image:url('/Images/StarFade.gif');
    min-width:30px;
    min-height:30px;
    display:inline-block;
    cursor:pointer;
}

.starFadeN{
    background-image:url('/Images/StarFade.gif');
    min-width:30px;
    min-height:30px;
    display:inline-block;
}

.starGlow{
    background-image:url('/Images/starglow.gif');
    min-width:30px;
    min-height:30px;
    display:inline-block;
    cursor:pointer;
}
.starGlowN{
    background-image:url('/Images/starglow.gif');
    min-width:30px;
    min-height:30px;
    display:inline-block;
}

Star rating system view - /Views/Articles/Details.cshtml
This page converts the comments to it's original type and then retrieve the ViewBag value of ratingSum and ratingCount. Do the math to calculate the average of the rating that will be used to show the rating for the post.

@model StarRatingSystem.Models.Article

@{
    ViewBag.Title = Model.Title;
    var comments = (IEnumerable<StarRatingSystem.Models.ArticlesComment>)ViewBag.Comments;
    var ratingSum = ViewBag.RatingSum;
    var ratingCount = ViewBag.RatingCount;

    decimal rating = 0;
    if (ratingCount > 0)
    {
        rating = (ratingSum / ratingCount);
    }
    var totalRating = decimal.Parse(rating.ToString());
}

<h2>@Model.Title</h2>
<div>
    <span class="starFadeN" id="sRate1"></span><span class="starFadeN" id="sRate2"></span><span class="starFadeN" id="sRate3"></span><span class="starFadeN" id="sRate4"></span><span class="starFadeN" id="sRate5"></span>
</div>
<div>
    <dl class="dl-horizontal">
      
        <dt>
            @Html.DisplayNameFor(model => model.Description)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Description)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Active)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Active)
        </dd>

    </dl>
</div>
@foreach(var c in comments)
{
    <hr />
    <div class="row">
        <div class="col-md-3">
            <i>@c.ThisDateTime</i>
            <br />
            @for (var i = 1; i <= c.Rating; i++)
            {
                <span class="starGlowN"></span>
            }
            @for (var i = (c.Rating + 1); i <= 5; i++)
            {
                <span class="starFadeN"></span>
            }
        </div>
        <div class="col-md-9">
            @Html.Raw(c.Comments.Replace("\n", "<br />"))


            </div>
        </div>
}
<hr />
@Html.Partial("_CommentBox")

<script>
    function SCRate() {
        for (var i = 1; i <= @totalRating; i++) {
            $("#sRate" + i).attr('class', 'starGlowN');
        }
    }
    $(function(){
        SCRate();
    });
</script>

Notice the bold part above where we are using 'starFadeN' css class. This simply shows the faded version of the star however when the page loads, SCRate() javascript function is called to convert those classes to 'starGlowN' based on the average of ratings  (totalRating) calculated above.
Comment box - /Views/Shared/_CommentBox.cshtml
This is the most important part of the entire Star rating system project. This allows visitor to rate the post along with commenting on the post.

This page does following
  1. When the form is submitted SubmitComment() function is called that checks if the user has rated this post or not, if not it shows an alert message to rate this post.
  2. When use over the mouse on the faded star it raises following events
    • onclick - set the value of the current star rating value to the hidden field
    • onmouseover - shows the glowing star
    • onmouseout  - shows the faded star
    • all starts are clubbed in a div that has onmouseout event that simply re-glow all the stars that was initially selected by the visitor.

<dl class="dl-horizontal">
    <dt>
        Comment
    </dt>

    <dd>
        <div class="commentBox">
            @using (Html.BeginForm("Add", "ArticlesComments", FormMethod.Post, new { onsubmit = "return SubmitComment()" }))
            {
                @Html.AntiForgeryToken()
                <div class="form-horizontal">
                    <div class="form-group">
                        <label class="col-md-4 control-label">
                            Your rating <span style="font-weight:normal;">(1 start is bad, 5 star is good)</span>
                        </label>
                        <div class="col-md-7">
                            <div onmouseout="CRateSelected()">
                                <span class="starFade" id="Rate1" onclick="CRate(1)" onmouseover="CRateOver(1)" onmouseout="CRateOut(1)"></span><span class="starFade" id="Rate2" onclick="CRate(2)" onmouseover="CRateOver(2)" onmouseout="CRateOut(2)"></span><span class="starFade" id="Rate3" onclick="CRate(3)" onmouseover="CRateOver(3)" onmouseout="CRateOut(3)"></span><span class="starFade" id="Rate4" onclick="CRate(4)" onmouseover="CRateOver(4)" onmouseout="CRateOut(4)"></span><span class="starFade" id="Rate5" onclick="CRate(5)" onmouseover="CRateOver(5)" onmouseout="CRateOut(5)"></span>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-12">
                            <textarea name="Comment" id="Comment" required rows="5" style="width:100%;" class="form-control"></textarea>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-12">
                            <input type="hidden" name="ArticleId" value="@ViewBag.ArticleId" />
                            <input type="hidden" name="Rating" id="Rating" value="0" />
                            <input type="submit" id="btnRegister" name="btnRegister" value="Submit Comment" class="btn btn-warning" />
                        </div>
                    </div>
                </div>
            }
        </div>
    </dd>

</dl>
<script>
    function SubmitComment() {
        if ($("#Rating").val() == "0") {
            alert("Please rate this service provider.");
            return false;
        }
        else {
            return true;
        }
    }

    function CRate(r) {
        $("#Rating").val(r);
        for (var i = 1; i <= r; i++) {
            $("#Rate" + i).attr('class', 'starGlow');
        }
        // unselect remaining
        for (var i = r + 1; i <= 5; i++) {
            $("#Rate" + i).attr('class', 'starFade');
        }
    }

    function CRateOver(r) {
        for (var i = 1; i <= r; i++) {
            $("#Rate" + i).attr('class', 'starGlow');
        }
    }

    function CRateOut(r) {
        for (var i = 1; i <= r; i++) {
            $("#Rate" + i).attr('class', 'starFade');
        }
    }

    function CRateSelected() {
        var setRating = $("#Rating").val();
        for (var i = 1; i <= setRating; i++) {
            $("#Rate" + i).attr('class', 'starGlow');
        }
    }
</script>

The complete implementation looks like below


Star rating system Source code & Demo

The complete source code of this article is available at https://github.com/dotnetfunda/StarRatingSystem , feel free to download, upgrade and check in so that all gets benefited.

The demo of this star rating system can be see here.

Thanks for reading this post, if this helps do share to your friends and colleges or let me know your feedback by responding to this article.
Recommendation
Read Using MySQL with Entity Framework in ASP.NET MVC after this article.
Page copy protected against web site content infringement by Copyscape

About the Author

Sheonarayan
Full Name: Sheo Narayan
Member Level: HonoraryPlatinum
Member Status: Administrator
Member Since: 7/8/2008 6:32:14 PM
Country: India
Regards, Sheo Narayan http://www.dotnetfunda.com

Ex-Microsoft MVP, Author, Writer, Mentor & architecting applications since year 2001. Connect me on http://www.facebook.com/sheo.narayan | https://twitter.com/sheonarayan | http://www.linkedin.com/in/sheonarayan

Login to vote for this post.

Comments or Responses

Posted by: Jayakumars on: 4/22/2017 | Points: 25
Hi
Sheo

In this Star rating system Coding issue come how to fixed in my pc?


Issue is

An exception of type 'System.Data.Entity.Core.EntityCommandExecutionException' occurred in EntityFramework.SqlServer.dll but was not handled in user code

Additional information: An error occurred while executing the command definition. See the inner exception for details.

can you guide me how to fixed this?
Posted by: Coolrishu on: 4/30/2017 | Points: 25
Hi Sheo Narayan
Thanks for artcile. But my requirement is to get ratings in point also like 3.5 star or 4.5 star. So how can I do it?
Please suggest.

Login to post response

Comment using Facebook(Author doesn't get notification)