A visitor group criterion is used in EPiServer to let editors choose criterias when certain content should be showed or not. EPiServer comes with a few default ones but usually you need to create your own ones. Here is a little guide on how to get it working in EPiServer 7 MVC.

We did this for a client that needed to trigger content depending on which Market you have chosen. The market is saved in a cookie.

First off, you need to create two classes. One for the Model of what data you need, and one that matches the current info against the data.

Start off by creating a Settings file

using System.ComponentModel.DataAnnotations;
using System.Linq;
using EPiServer.Personalization.VisitorGroups;
using www.Handlers;

namespace www.Personalization.Market
{
	public class MarketCriterionSettings : CriterionModelBase
	{
		[Required]
		public string MarketCode { get; set; }

		public override ICriterionModel Copy()
		{
			return ShallowCopy();
		}
}

You can also put your own validation here if needed. All you need to do is to inherit IValidateCriterionModel and implement the method Validate. Doing this our file would look like this instead:

using System.ComponentModel.DataAnnotations;
using System.Linq;
using EPiServer.Personalization.VisitorGroups;
using www.Handlers;

namespace www.Personalization.Market
{
	public class MarketCriterionSettings : CriterionModelBase, IValidateCriterionModel
	{
		[Required]
		public string MarketCode { get; set; }

		public override ICriterionModel Copy()
		{
			return ShallowCopy();
		}

// Custom validation to be sure that the market exists.
		public CriterionValidationResult Validate(VisitorGroup currentGroup)
		{
			return new CriterionValidationResult(MarketHandler.Instance.GetAllMarkets().Any(m => m.UrlCode == MarketCode), "The market does not exist");
		}
}

Next up is to create the Criterion. This one needs to be decorated with the VisitorGroupCriterion attribute and inherit from CriterionBase

using System.Security.Principal;
using System.Web;
using EPiServer.Personalization.VisitorGroups;
using www.Handlers;

namespace www.Personalization.Market
{
	[VisitorGroupCriterion(
		Category = "Market",
		DisplayName = "Current Market",
		Description = "Check if the user is using current market"
	)]
	public class MarketCriterion : CriterionBase<MarketCriterionSettings>
	{
		public override bool IsMatch(IPrincipal principal, HttpContextBase httpContext)
		{
			return MarketHandler.Instance.CurrentMarket.UrlCode.ToLower().Equals(Model.MarketCode.ToLower());
		}
	}
}

If you are using CMS6, that’s it! However, right now in EPiServer 7 there is a bug 🙁 So if you try to save at this moment you would get an error saying “Failed to convert item”. The bug claims to be fixed in EPiServer 7 Patch 1, but I am using Patch 3 and still get the error so something isn’t working correctly. However, there is a easy fix for this. In /Views/Shared/EditorTemplates create a new partial view that is named as your model/settings. Such as MarketCriterionSettings.cshtml for my example.

@using EPiServer.Personalization.VisitorGroups
@model www.Personalization.Market.MarketCriterionSettings

<div class="epi-criteria-grouping">
	<span class="epi-criteria-inlineblock">
		@Html.DojoEditorFor(x => x.MarketCode)
	</span>
</div>

Now you have a working new criteria in you Visitor Groups section in EPiServer.