Hide menu Last updated: Jun 01 2017
Area: Episerver Social Applies to versions: 1.4 and higher
Other versions:

Managing ratings

In the Episerver Social Platform, ratings and rating statistics are managed through a service implementing the IRatingService and IRatingStatisticsService interfaces, respectively. These services provide the ability to persist, retrieve, and remove ratings that you define and their associated rating statistics.

Accessing an IRatingService

If the Ratings feature is installed to an Episerver CMS site via the feature's site integration package, get an instance of this service from the inversion of control (IoC) container.

Example:

var ratingService = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IRatingService>();

If the feature is installed to a non-Episerver CMS site, get an instance of a service from the default factory class provided in the package.

Example:

var factory = new EPiServer.Social.Ratings.Factories.DefaultRatingServiceFactory();
var ratingService = factory.Create();

Adding a rating

Add a rating by using the Add(Rating) method of the IRatingService. This method accepts an instance of the Rating class and returns a reference to a new instance of that class, which has been populated with any additional, system-generated data (for example, a unique ID).

IRatingService ratingService;

// ...

var rater = Reference.Create("user://identifier/for/a/user");
var target = Reference.Create("resource://identifier/for/a/resource");
var ratingValue = new RatingValue(5);

var rating = new Rating(rater, target, ratingValue);

ratingService.Add(rating);

The service permits one rating per rater and target combination. If an attempt is made to add another rating for an existing rater and target combination, a DuplicateRatingException is thrown.

In the above example, the request to add a rating is invoked synchronously. An example of adding a rating asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task<Rating> AddRatingAsync(IRatingService ratingService)
{
    // ...

    var rater = Reference.Create("user://identifier/for/a/user");
    var target = Reference.Create("resource://identifier/for/a/resource");
    var ratingValue = new RatingValue(5);

    var rating = new Rating(rater, target, ratingValue);

    var addRatingTask = ratingService.AddAsync(rating);

    //Do other application specific work in parallel while the task executes.
    //....

    //Wait until the task runs to completion.
    var newRating = await addRatingTask;
    return newRating;
}

Updating a rating

To update a rating, which has been added through the platform, use the Update(RatingId,RatingValue,RatingValue) method of the IRatingService. This method accepts the ID of the rating to be updated (RatingId), the current value of the rating (RatingValue), and the new value of the rating to be set (RatingValue).

Note: This method accepts the current value of your Rating, in addition to the new value, to ensure consistency in the calculation of the statistical measures associated with that Rating.

IRatingService ratingService;
Rating originalRating;

// ...

ratingService.Update(originalRating.Id, originalRating.Value, new RatingValue(5));

If the rating to be updated does not exist or the specified current value is no longer consistent with the stored representation of that rating, a RatingDoesNotExistException is thrown.

If the identified rating is a Composite Rating, its value is updated, and its associated extension data remains intact. (For more information on Composite Ratings, see Extending Ratings with Composites.)

In the above example, the request to update a rating is invoked synchronously. An example of updating a rating asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task<Rating> UpdateRatingAsync(IRatingService ratingService)
{
    // ...

    Rating originalRating;

    var updateRatingTask = ratingService.UpdateAsync(originalRating.Id, originalRating.Value, new RatingValue(5));

    //Do other application specific work in parallel while the task executes.
    //....

    //Wait until the task runs to completion.
    var updatedRating = await updateRatingTask;
    return updatedRating;
}

Retrieving a rating

To retrieve a specific instance of a rating added through the platform, use the Get(RatingId) method of IRatingService. This method accepts an instance of the RatingId class, which identifies the rating to be retrieved. It returns the instance of the Rating class corresponding to that identifier.

IRatingService ratingService;

//...

// Construct a RatingId corresponding to the desired rating
var ratingId = RatingId.Create("...");
var rating = ratingService.Get(ratingId);

If the requested rating cannot be found, a RatingDoesNotExistException is thrown.

In the above example, the request to retrieve a rating is invoked synchronously. An example of retrieving a rating asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task<Rating> GetRatingAsync(IRatingService ratingService)
{
    Rating existingRating;

    // ...

    // Construct a RatingId corresponding to the desired Rating
    var ratingId = RatingId.Create("...");

    var getRatingTask = ratingService.GetAsync(ratingId);

    //Do other application specific work in parallel while the task executes.
    //....

    //Wait until the task runs to completion.
    var rating = await getRatingTask;
    return rating;
}

To retrieve a collection of ratings added through the platform, use the Get(Criteria<RatingFilter>) method. This method accepts an instance of Criteria<RatingFilter>, which contains the specifications necessary to retrieve the desired ratings.

The Filter property of the Criteria<RatingFilter> class accepts an instance of the RatingFilter class. This class contains specifications that let you refine the result set of ratings being retrieved. The RatingFilter properties include:

  • Rater. Assign a value (Reference) to this property to refine a result set to ratings contributed by the identified user.
  • Targets. Assigning a value (IEnumerable<Reference>) to this property refines a result set to ratings for the identified users or resouces included in that collection.

You may apply the RatingFilter specifications in conjunction with one another. Each specification assigned a value in the filter further refines the result set (that is, a logical AND).

The example below demonstrates the retrieval of a result page of ratings that were contributed for a particular resource.

IRatingService ratingService;

// ...

var target = Reference.Create("resource://identifier/for/a/resource");
var criteria = new Criteria<RatingFilter>
{
    Filter = new RatingFilter
    {
        Targets = new List<Reference> { target }
    }
};

var pageOfRatings = ratingService.Get(criteria);

In the next example, a similar approach demonstrates the retrieval of a result page of ratings that were contributed by a particular user.

IRatingService ratingService;

// ...

var contributingUser = Reference.Create("user://identifier/for/a/user");
var criteria = new Criteria<RatingFilter>
{
    Filter = new RatingFilter
    {
        Rater = contributingUser
    }
};

var pageOfRatings = ratingService.Get(criteria);

In the above examples, the request to retrieve ratings is invoked synchronously. An example of retrieving ratings asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task<ResultPage<Rating>> GetRatingsAsync(IRatingService ratingService)
{
    // ...

    var contributingUser = Reference.Create("user://identifier/for/a/user");
    var criteria = new Criteria<RatingFilter>
    {
        Filter = new RatingFilter
        {
            Rater = contributingUser
        }
    };

    var getRatingsTask = ratingService.GetAsync(criteria);

    //Do other application specific work in parallel while the task executes.
    //....

    //Wait until the task runs to completion.
    var pageOfRatings = await getRatingsTask;
    return pageOfRatings;
}

The RatingSortFields class exposes a set of fields upon which you can order a result set of ratings. You can apply these fields in the construction of sorting rules that you associate with your criteria. These fields include:

  • RatingSortFields.Id
  • RatingSortFields.Created
  • RatingSortFields.Modified
  • RatingSortFields.Value
  • RatingSortFields.Rater
  • RatingSortFields.Target

The example below shows how to apply sorting rules to order a result set by value, from highest to lowest. A fallback rule, subsequently ordering results with the same value by creation date (from newest to oldest), is also added.

var criteria = new Criteria<RatingFilter>
{
    // ...

    OrderBy = new List<SortInfo>
    {
        new SortInfo(RatingSortFields.Value, false),
        new SortInfo(RatingSortFields.Created, false),
    }
};

For details on the use of criteria, including paging and sorting information, see Criteria.

Removing a rating

To remove a specific instance of rating, which was previously added through the platform, use the Remove(RatingId) method. This method accepts an instance of the RatingId class, which identifies the RatingId to be removed. The result is the deletion of the rating corresponding to that ID.

IRatingService ratingService;

// ...

// Construct or retrieve an ID for an existing rating.
var ratingId = RatingId.Create("...");
ratingService.Remove(ratingId);

In the above example, the request to remove a rating is invoked synchronously. An example of removing a rating asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task RemoveRatingAsync(IRatingService ratingService)
{
    // ...

    // Construct or retrieve an ID for an existing rating.
    var ratingId = RatingId.Create("...");

    var removeRatingTask = ratingService.RemoveAsync(ratingId);

    //Do other application specific work in parallel while the task executes.
    //....

    //Wait until the task runs to completion.
    await removeRatingTask;
}

Accessing an IRatingStatisticsService

If the Ratings feature is installed to an Episerver CMS site via the feature's site integration package, get an instance of this service from the inversion of control (IoC) container.

Example:

var statisticsService = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IRatingStatisticsService>();

If the feature is installed to a non-Episerver CMS site, get an instance of a service from the default factory class provided in the package.

Example:

var factory = new EPiServer.Social.Ratings.Factories.DefaultRatingStatisticsServiceFactory();
var statisticsService = factory.Create();

Retrieving statistics

As ratings are added to and removed through the platform, simple statistics are automatically tabulated for targeted resources. You can retrieve the statistics to tabulate metrics for your rated resources. Within the platform, this information is represented with the RatingStatistics class.

namespace EPiServer.Social.Ratings.Core
{
    //
    // Summary:
    //     This class represents the statistical information for the ratings of an individual
    //     referenced item.
    public class RatingStatistics
    {
        //
        // Summary:
        //      Gets the unique identifier for the statistics generated by the 
        //      Social platform.
        public StatisticsId Id { get; }
        //
        // Summary:
        //     Gets the sum of all ratings for an item.
        public long Sum { get; }
        //
        // Summary:
        //     Gets a reference to the target the statistics applies to.
        public Reference Target { get; }
        //
        // Summary:
        //     Gets the total number of ratings for an item.
        public long TotalCount { get; }
        //
        // Summary:
        //     Gets the mean value of the ratings for an item.
        //
        public double Mean { get; }
    }
}

The statistical information in this class includes:

  • Target. Reference to the resource to which the statistics apply.
  • Sum. The sum of all rating values attributed to the target resource.
  • TotalCount. The total count of all ratings attributed to the target resource.
  • Mean. The mean value of all ratings attributed to the target resource.

With this information, rating counts, sums, and averages may be tabulated within your application.

To retrieve a collection of RatingStatistics, use the Get(Criteria<RatingStatisticsFilter>) method of IRatingService. This method accepts an instance of the Criteria<RatingStatisticsFilter> class. This class contains specifications that let you refine the result set of rating statistics being retrieved.  The RatingStatisticsFilter properties include:

  • Targets. Assigning a value (IEnumerable<Reference>) to this property refines a result set to rating statistics for the identified users or resouces included in that collection.
IRatingStatisticsService statisticsService;

// ...

var ratedResource = Reference.Create("resource://identifier/for/a/resource");
var criteria = new Criteria<RatingStatisticsFilter>
{
    Filter = new RatingStatisticsFilter 
    {
        Targets = new List<Reference> { ratedResource }
    }
};

var pageOfRatingStatistics = statisticsService.Get(criteria);

The RatingStatisticsSortFields class exposes a set of fields upon which you can order a result set of rating statistics. You can apply these fields in the construction of sorting rules that you associate with your criteria. These fields include:

RatingStatisticsSortFields.Target
RatingStatisticsSortFields.TotalCount
RatingStatisticsSortFields.Sum
RatingStatisticsSortFields.Mean

The example below shows how to apply sorting rules to order a result set by the Sum field of the RatingStatistics retrieved, from highest to lowest. A fallback rule, subsequently ordering results with the same value of the Sum field by target reference (in ascending order), is also added.

var criteria = new Criteria<RatingStatisticsFilter>
{
    // ...

    OrderBy = new List<SortInfo>
    {
        new SortInfo(RatingStatisticsSortFields.Sum, false),
        new SortInfo(RatingStatisticsSortFields.Target, true),
    }
};

If an application has more sophisticated statistical needs, you can implement custom analyses by leveraging the paged retrieval of ratings available through the Get(Criteria) method of IRatingStatisticsService. Your application may interpret and tabulate those ratings according to its needs.

In the above example, the request to retrieve rating statistics is invoked synchronously. An example of retrieving rating statistics asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task<ResultPage<RatingStatistics>> GetRatingStatisticsAsync(IRatingStatisticsService statisticsService)
{
    // ...

    var ratedResource = Reference.Create("resource://identifier/for/a/resource");
    var criteria = new Criteria<RatingStatisticsFilter>
    {
        Filter = new RatingStatisticsFilter 
        {
            Targets = new List<Reference> { ratedResource }
        }
    };

    var getRatingStatisticsTask = statisticsService.GetAsync(criteria);

    //Do other application specific work in parallel while the task executes.
    //....

    //Wait until the task runs to completion.
    var pageOfRatingStatistics = await getRatingStatisticsTask;
    return pageOfRatingStatistics;
}

Comments