Try our conversational search powered by Generative AI!

Carlos Colon
Mar 3, 2017
(8 votes)

Building a Like button with Episerver Social Ratings


In this tutorial, we are going to show how to build a Like button with the Episerver Social Ratings service API [1]. A Like button has a few simple requirements:

  • Track the total number of times the Like button was clicked.
  • Determine if a user with a known identity has already Liked the page.

For the purposes of this tutorial and to keep the implementation simple, the tutorial code will let anonymous users rate as many times as they choose. The full source code for the tutorial is available in our SocialAlloy repo [2].


To use the Social Ratings service API, install the EPiServer.Social.Ratings NuGet package, available in the Episerver NuGet feed [4], to your project or solution. If using the Social Ratings service API in an Episerver site, you should also install the EPiServer.Social.Ratings.Site package to leverage Episerver’s ServiceLocator container to create the Social Ratings service instance. The SocialAlloy repo [2] already has these packages installed and will be restored when the solution is built.

Building the Like button

Keep in mind that the full source in the SocialAlloy repo [2] is for educational purposes and is not production quality. As implemented, the Like button has the following components: 

1.     An Episerver Block

A block is used to add a Like button to any page in the SocialAlloy site.

2.     A Like button controller

The Like button controller is the business logic implementation of the Like button functionality. The controller has three public methods: 

  • Constructor method – In the constructor, global resources needed by other public methods are allocated. The controller needs an instance of the ratings service to be able to retrieve and save Like ratings. Installing the EPiServer.Social.Ratings.Site package enables the use of Episerver’s ServiceLocator to allocate that instance.
this.ratingService = ServiceLocator.Current.GetInstance<IRatingService>();
  • Index method – This method contains the business logic that renders the block’s front end view in whatever page the block is currently executing on. As for the ratings API usage, the critical parts of this method are: 
    • Get the rating for a user with an identity (does not apply to anonymous users). The rating filter is supplied with a user rater and page target references. Since a count of only one item is expected to match the criteria, we specify a PageSize of one. 
var ratingPage = ratingService.Get(
        new Criteria<RatingFilter>
               Filter = new RatingFilter
                       Rater = raterUserRef,
                       Targets = new List<Reference>
               PageInfo = new PageInfo
                       PageSize = 1
    • Get Like statistics for the current page. We are interested in the total number of Likes the current page has received across all users. 
var ratingStatisticsPage = ratingService.Get(
               new Criteria<RatingStatisticsFilter>
                              Filter = new RatingStatisticsFilter
                                             Targets = new List<Reference>
                              PageInfo = new PageInfo
                                             PageSize = 1
  • Submit method – This method contains the business logic that handles a user clicking the Like button in the block’s front end view in whatever page the block is currently executing. As for the rating API usage, the critical functionality of this method is to use the rating service Add API to save the Like for the user (rater) and the current page (target). Because Like is a very simple rating, we store the rating as Liked_Rating = 1.
var addedRating = ratingService.Add(
               new Rating(
                              new RatingValue(Liked_Rating)

3.     A Like button block front end view model

The controller needs to provide data to the Like button view. We need a model to store that data, so the view can access it while it is rendered. The Like button block view model is implemented as follows: 

public class LikeButtonBlockViewModel
        public LikeButtonBlockViewModel(){}

        public PageReference PageLink { get; set; }

        public long TotalCount { get; set; }

        public int? CurrentRating { get; set; }

The empty constructor is required by the CMS framework, since it needs to create the model when the block view form is submitted back to the server. We also need the reference to the current page for use by the Like button click handler on the server side. The TotalCount and the CurrentRating are rating specific properties.

  • TotalCount stores the total count of clicks across all users.
  • CurrentRating stores the Like rating (i.e., Liked_Rating) for the current user, if any.

4.     A Like button view

The Like button block needs a view to render itself in the front end. That view is implemented as follows: 

<div class="border">
    <div style="margin-top:0.5em">
        @if (Model.CurrentRating.HasValue)
            <div> You have already <i class="icon-thumbs-up"></i> this page! </div>
            using (Html.BeginForm("Submit", null))
                @Html.HiddenFor(m => m.PageLink)
                    <button name="submitsocialrating" value="Submit" class="btn-primary"><i class="icon-thumbs-up"></i> Like </button>
        <div><strong>Likes: @Model.TotalCount</strong></div>

If there is a rating value for the current user, meaning the user has previously Liked the page, then the view reflects that. In that case, do not allow the current user to Like the page again by not displaying the Like button.

If there is no Like rating value for the current user, which is always the case for anonymous users, then display the Like button. Finally, the view shows the total count of Likes for the page across all users.


[1] Episerver Social Developer Guide -- 

[2] Full tutorial code:




[3] Tutorial code views -- 

[4] Episerver NuGet feed --

Mar 03, 2017


Please login to comment.
Latest blogs
Build a headless blog with Astro and Optimizely SaaS CMS

I’m a big fan of using the right tool for the right job. I’m also a big fan of Astro , for the right use case. Let's explore Astro to see what it's...

Jacob Pretorius | May 28, 2024

Microsoft announces Natural language to SQL

Finally, Microsoft launches "Natural language to SQL," after it has been available for several months in Optimizely CMS!

Tomas Hensrud Gulla | May 23, 2024 | Syndicated blog

Five easy ways to start personalizing your content right now

If you clicked on this article, you already know that getting the right message to the right person at the right time helps drive conversions and...

Kara Andersen | May 23, 2024

ExtendedCms.TinyMceEnhancements – serwer side webp support

Today I will introduce another small feature of TinyMceEnhancements plugin. The functionality is used to automatically detect whether a browser...

Grzegorz Wiecheć | May 22, 2024 | Syndicated blog

Azure AI Language– Detect Healthcare Content in Optimizely CMS

In this blog post, I showcase how the Azure AI Language service's Text Analytics for health feature can be used to detect healthcare content within...

Anil Patel | May 22, 2024 | Syndicated blog

Stott Security Version 2 So Far

In December 2023, I unveiled the initial version of Stott Security version 2. Although I typically announce each version I release on LinkedIn and...

Mark Stott | May 22, 2024