6

I need an assist. I'm running into a situation where code that was written for a custom rule is not firing. I have put breakpoints in Visual Studio and the breakpoints are never hit.

My solution is an Sitecore MVC website using Sitecore version 8.1 Update 3. The Rule is configured through Presentation Details of a rendering component.

The custom rule code was a WhenCondition after getting feed back from Mark Cassidy, it's been changed to a StringOperatorCondition.

I have done the following:

  1. Created a Rule Folder item and added it the the Rule item's Tags under Default
  2. Created Element Folder
    1. Created Rule Condition item
      • In the Data section Text field there is this text:
        where the cookie [operatorid,StringOperator,,compares to] [Value,,,specific value]
      • In the Script section Type field I have put the MyNamespace.Class, Assembly Name
    2. Added Rule to Tags in the Default Tags Definition

I am looking for debugging suggestions. On the surface this seems like I haven't configured something correctly. I can't see what the is. In the Rules Cookbook for 7.1+, there is mention that the rule should be added to the Standard Values of a template. Is this really needed in Sitecore 8.1 Update 3?

***UPDATE: I have double checked my configuration against Sitecore 8 – Create a custom personalization rule. I changed my code as @MarkCassidy suggested. (I am in no way saying what Mark suggested is any reason why the logic is not being called. What he suggests seems like the right approach.) I am still scratching my head as to what I'm missing. I also changed the Text in my Rules Condition. The value is updated above.

**SOLUTION: The solution ultimately was the I had the wrong xdb setting enabled. I had xdb.enabled, and xdb.tracking.enabled = false, so the rules weren't firing. Mark pointed that out in the solution comments below.

Here is the refactored custom rule code (After this refactor the rule is still not firing):

public class ZipCookieCondition<T> : StringOperatorCondition<T> where T : RuleContext
{
    public string Value { get; set; }  //StateName

    protected override bool Execute(T ruleContext)
    {
        Assert.ArgumentNotNull(ruleContext, "ruleContext");                        

        var locationCookie = HttpContext.Current.Request.Cookies["LocationCookie"];
        if (locationCookie == null)
        {
            return false;
        }
        //Cookie is Http Encoded because front-end uses Cookie.js and is
        //storing a JSON object as the value
        var cookieVal = string.IsNullOrEmpty(locationCookie.Values["state"])
            ? DecodeCookieValue(locationCookie)
            : locationCookie.Values["state"];

        if(!string.IsNullOrEmpty(cookieVal))
            return Compare(cookieVal.ToLowerInvariant(), Value.ToLowerInvariant());

             return false;
    }

    private string DecodeCookieValue(HttpCookie locationCookie)
    {
        var cookieValue = HttpUtility.UrlDecode(locationCookie.Value);
        var locationObj = JsonConvert.DeserializeObject<LocationCookie>(cookieValue);
        if (locationObj != null)
        {
           return locationObj.State;
        }

        return string.Empty;
    }
}

internal class LocationCookie
{
    public string State { get; set; }
    public string ZipCode { get; set; }        
}
8
  • Creating the rule itself is not enough. Where is the rule being used? Did you set it up as a conditional rendering or something else?
    – Mark Cassidy
    Commented Mar 30, 2017 at 14:17
  • @MarkCassidy I use the rule for personalization. The rule was added as a condition in Presentation Details using the Content Editor to a rendering component.
    – Derek Port
    Commented Mar 30, 2017 at 14:22
  • Right. Please post the WhenCondition<T> code as well. Sitecore invokes it by reflection and it's fairly picky when doing so.
    – Mark Cassidy
    Commented Mar 30, 2017 at 14:42
  • Have you published everything? Personalization is only applied in normal mode
    – Marek Musielak
    Commented Mar 30, 2017 at 14:43
  • @MarekMusielak Yes I did a site republish just to be sure.
    – Derek Port
    Commented Mar 30, 2017 at 14:53

1 Answer 1

4

What you're building isn't really a WhenCondition<>. It's a StringOperatorCondition<>.

As it stands right now, your code pays no attention to the operatorwhich would be configurable in the rule via your definition string.

where the cookie [operatorid,StringOperator,,compares to] [value,,,value]

While you could extend your class for this, it would be much easier for you to base your code on a different base class. I'll do a bit of it here:

public class CookieValueCondition<T> : StringOperatorCondition<T> where T : RuleContext
{
    public string Value { get; set; }

    protected override bool Execute(T ruleContext)
    {
        return Compare(GetCookieValue("LocationCookie"), Value);
    }
}

GetCookieValue() being your cookie functionality from above.

I would also suggest you expand your rule to also take the Cookie Name as a variable parameter, but that's perhaps a story for a different day :-)

I presented at SUGDE recently, where I presented this and many other possibilities with the Rules Engine. The repo is publically available here:

edited to add

I should add; to make your code work more or less as-is, change your definition text to this.

where the Location Cookie is [value,,,value]

This would make it a pure WhenCondition and should work as-is. Right now, Sitecore is trying to find your referenced operatorid property and failing, which is likely why your code does not execute at all.

5
  • Is there any convention that has to be adhered to when naming your class as it relates to the name of the Element definition or Cookie Rule Folder name?
    – Derek Port
    Commented Mar 30, 2017 at 16:36
  • No. Your class is exclusively determined by what you put in the type field of your definition item (below your definition text). Like this: Sitecore.Buckets.Rules.Bucketing.Conditions.WhenBucketIdIs,Sitecore.Buckets
    – Mark Cassidy
    Commented Mar 30, 2017 at 16:38
  • This didn't fix my issue. I updated my code to be the StringOperatorCondition. I updated the summary above with the latest code and config changes. I can't mark this as the answer yet, but I think it certainly is the right approach.
    – Derek Port
    Commented Mar 30, 2017 at 19:51
  • 2
    Right. 1 thing to check. Is Tracking enabled? Without it, Sitecore won't even bother running personalisation rules. See sitecore.stackexchange.com/a/4769/73
    – Mark Cassidy
    Commented Mar 30, 2017 at 21:23
  • 1
    Thanks for all of your help Mark. It turns out that I had the wrong xdb setting enabled. I had xdb.enabled = true but xdb.tracking.enabled = false. I feel very sillly now. I did learn something, so that's a plus. Once I turned tracking on it worked like a charm.
    – Derek Port
    Commented Mar 31, 2017 at 1:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.