Custom visitor group criterion state storage in Epi 10

Vote:
 

I want that visitors can see content only if the URL contains a specific key and value in url-parameters, for example `?clienttype=business`.

For that i have created following classes.

Setting class:

[EPiServerDataStore(AutomaticallyRemapStore = true)]
[PublicAPI("Used in module episerver vistorgroups")]
public class UrlParameterValidationSettings : CriterionModelBase, IValidateCriterionModel, ICriterionSettings
{
    public CriterionValidationResult Validate(VisitorGroup currentGroup)
    {
		if (string.IsNullOrWhiteSpace(Key))
		{
			return new CriterionValidationResult(false, $"{nameof(Key)} must not be empty");
		}
		if (string.IsNullOrWhiteSpace(Value))
		{
			return new CriterionValidationResult(false, $"{nameof(Value)} must not be empty");
		}

		return CriterionValidationResult.Valid;
	}

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

	public string Key { get; set; }
	public string Value { get; set; }

	public bool IsDeny { get; set; }
}

Criterion class:

[VisitorGroupCriterion(
	Category = "Custom Criterion",
	DisplayName = "URL-Parameter exists with a given value",
	Description = "Checks if a URL-Parameter exists with a given value")]
public class UrlParameterValidationCriterion : CriterionBase<UrlParameterValidationSettings>
{
	public override bool IsMatch(IPrincipal principal, HttpContextBase httpContext)
	{
		NameValueCollection requestParameters = httpContext.Request.QueryString;
		string value = requestParameters[Model.Key];
		bool matchingUrlParameter = value != null && StringComparer.InvariantCultureIgnoreCase.Equals(Model.Value, value);
		return Model.IsDeny ? !matchingUrlParameter : matchingUrlParameter;
	}
}


It works. But now i want that it will be validated only once and then keeps it value the whole browser-session. Currently it seems that it checks the url-parameter on every request. 

Even if i use the builtin "Visitor Group Membership" and add there a custom visitor group with the above criterion, it will always validate it on every request.

Is it a misunderstanding on my side how visitor groups work, or what is the correct way to implement this requirement? 

We are still on EPI 10 but will switch to 11 soon. Is this change in EPI11 what i am looking for or is it already possible in 10?

#207647
Edited, Sep 27, 2019 14:00
Vote:
 

Hi Tim,

Visitor groups are evaluated each time they are used (e.g. to display a piece of content) which allows for circumstances where personalisation is done based on changing data (e.g. time of day). This means that, if you need to persist the result of a custom-written criterion like the one above, you'll need to add in a mechanism to persist that data such as setting a cookie or storing the result to a session. The change you mention in 11 relates to the inbuilt criteria which use the session to persist data but, in Epi 11, can use cookies if the session has been disabled.

#207652
Sep 27, 2019 14:24
Vote:
 

Hi Tim

In your case you could probably change your criteria logic to:

  1. Search for and read a session cookie value. If available and it has a valid value, act on it and return.
  2. If the request has no such cookie, read the query string and decide if the criteria is matched (like you do now).
  3. Set a session cookie with the decision from bullet 2.

As Paul mentions, the criteria will be evaluated on all requests to pages where this criteria is added (could for instance be because of a block personalization group or a security group rule). But in this way, even though the criteria will be evaluated many times, the decision will be made only once per browser session.

#207664
Sep 27, 2019 21:43
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.