Digital Transformation

Sitecore 6.6 Tech Preview – MVC Conditional Rendering Bug & Fix

Brief Bug Description:
As soon as a change is made and published to attempt to Personalize a Rendering in Sitecore 6.6 rev. 120622 (Technical Preview), an error will be encountered on the page where the personalization has been set up on any MVC site.  The error is “Method ‘ToString’ in type ‘Sitecore.Mvc.Analytics.Presentation.EmptyRenderer’ from assembly ‘Sitecore.Mvc.Analytics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’ does not have an implementation.
The following post will describe how to recreate the above bug as well as how to adjust the Sitecore pipeline for CustomRendering.Personalize to a custom class that will fix the above bug.  The code / screenshots shown in this blog post is from a version of the MVC Music Store written in ASP.NET MVC 3 and integrated into Sitecore 6.6 rev. 120622.
Bug Recreation:
To recreate the bug, perform the following steps in a Sitecore 6.6 rev 120622 environment.
Screenshot of Sample Site Home Page before any personalization has been enabled:

Inside the Sitecore Desktop /  Content Editor, open up the Presentation Details of any Page item that has a rendering, and click Edit.

Next click “Controls”, then select the rendering you would like to enable DMS personalization on and hit the “Personalize Button”

You can now perform any action on this screen to personalize the rendering.  In my example, I will add a new condition and choose for my new condition to change the data source of the rendering if the website visitor has achieved a specific goal. (Note: Again, the actual specific action is immaterial to this step – you could choose to simply check the “Hide Component” checkbox of the default component, or choose a data source for that default and the end result would be the same as what I have done.)

Next, click OK until all of the pop-ups for the Sitecore Content Editor / Desktop have been closed and you are back to your page item.  This will inherently save your presentation changes.  You should now publish your item.

After your publish has completed successfully, navigate in a browser to the page you just made the personalization changes for.  You should now see the following error.

Bug Fix Process:
If you read through the bug details, you should realize that method that is encountering the error is the ApplyActions method in the class Sitecore.Mvc.Analytics.Pipelines.CustomizeRendering.Personalize.  The actual error itself is that the class Sitecore.Mvc.Analytics.Presentation.EmptyRenderer has no implementation of a ToString method.
The following workaround will have the developer replace the pipeline call to the class Sitecore.Mvc.Analytics.Pipelines.CustomizeRendering.Personalize with their own custom class (“CustomPersonalize” in our example), and then adjust the ApplyActions method of the custom class to call another custom class to replace the Sitecore.Mvc.Analytics.Presentation.EmptyRenderer.  This second custom class will implement a ToString method to remove the error.
First, create a new Class file in your VS Sitecore Project.  You may name the class whatever you’d like.  Replace your new class file’s content with the following code:

using System;
using System.IO;
using Sitecore.Diagnostics;
using Sitecore.Layouts;
using Sitecore.Mvc.Presentation;
using Sitecore.Rules.ConditionalRenderings;
using Sitecore.Mvc.Analytics.Pipelines.Response.CustomizeRendering;
namespace MVCTestSite.Common
{
public class CustomPersonalize : Personalize 
{
protected override void ApplyActions(CustomizeRenderingArgs args, ConditionalRenderingsRuleContext context)
{
Assert.ArgumentNotNull((object)args, "args");
Assert.ArgumentNotNull((object)context, "context");
RenderingReference reference = context.References.Find((Predicate<RenderingReference>)(r => r.UniqueId == context.Reference.UniqueId));
if (reference == null)
args.Renderer = (Renderer)new MVCTestSite.Common.CustomEmptyRenderer();
else
this.ApplyChanges(args.Rendering, reference);
}
}
public class CustomEmptyRenderer : Renderer
{
public override void Render(TextWriter writer)
{
Assert.IsNotNull((object)writer, "writer");
}
public override string ToString()
{
return string.Empty;
//throw new NotImplementedException();
}
}
}

 
Note that you may use whatever namespace / class names you like, but you will have to replace any instance of “MVCTestSite.Common” with your chosen namespace, and any “CustomEmptyRenderer” with the name of your second class.   The first class is inheriting from Sitecore.Mvc.Analytics.Pipelines.CustomizeRendering.Personalize and overriding the method ApplyActions.  The only difference in our override method from the Sitecore 6.6 original method is the line: “args.Renderer = (Renderer)new MVCTestSite.Common.CustomEmptyRenderer();”. The original Sitecore ApplyActions method sets args.Renderer equal to a new instantiation of the Sitecore.Mvc.Analytics.Presentation.EmptyRenderer class.
Our second class is going to be used in place of the Sitecore.Mvc.Analytics.Presentation.EmptyRenderer class.  The Render method in our second class is identical to that of the original class its replacing.  We have also added an override to the ToString method so that it returns string.Empty rather than throwing the NotImplementedException method which is the error we are trying to resolve.  (We can feel safe returning string.empty here because, as John West describes in his blog post, the EmptyRenderer is not to render anything.)
We now have our code that will bypass the above error completely, but we still need to put it into effect within the Sitecore pipeline.  We do that by making the following change to the file Sitecore.MvcAnalytics.config which is found in the App_Config/Include folder of our website.

Find and Replace the line:

<processor type="Sitecore.Mvc.Analytics.Pipelines.Response.CustomizeRendering.Personalize, Sitecore.Mvc.Analytics"/>

With:

<processor type="MVCTestSite.Common.CustomPersonalize, MVCTestSite"/>

(Where “MVCTestSite.Common” is the namespace you used for your above code, “CustomPersonalize” is the classname of the first class above, and “MVCTestSite” is the name of the DLL your site compiles into)
Once that is complete, you simply have to build your site and your page that was previously encountering an error should now work – personalization and all.
My example site after the above code was added and built:

The same page after I have achieved the goal “Added CD to Cart” (which is the condition of my personalization I made when recreating the bug).  Notice the red wording at the top:

You should now be set to add personalization to any page of your MVC site running on the Technical Preview version of Sitecore 6.6!
 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Jamie Stump

My name is Jamie Stump, and I am a Senior Sitecore Consultant at Perficient. I was honored to be named one of only 42 2013 Sitecore MVP’s worldwide. I specialize in Sitecore Architecture and Development and my broad Sitecore experience includes Sitecore installation, configuration and CEP development, including custom DMS implementations for clients. I have implemented Sitecore solutions for a number of industry verticals including manufacturing, healthcare, financial services, advertising and retail. In addition to architecting and implementing Sitecore sites and eCommerce solutions, I also work with other Microsoft Technologies, including the .NET platform and SQL Server. You can read through my older Sitecore related blog posts here and my newer ones here. I graduated with a Bachelor of Science in Information Systems Development from York College of PA. I am originally from the suburbs of Philadelphia, PA, and still reside there with my wife, son, English bulldog and 2 cats.

More from this Author

Follow Us
TwitterLinkedinFacebookYoutubeInstagram