We recently ran into an issue where the same code deployed to our authoring server wasn’t behaving as it should on our delivery servers. On each sever, we were making use of WebAPI to grab some data from the server and bind it to knockout. Seems easy enough, no? There’s a small catch though: Serialization.
On our CM, we saw the following:
On our CD, we saw the following:
That looks a lot like serialization issues, specifically something like what is mentioned in the Stack Overflow article here. Since I wasn’t stoked about adding DataContract/DataMember to all classes, I opted for forcing the serialization method. I’ll attach the code at the end. But for now, I’ll ask the obvious: “Why is this working on Authoring, but not Delivery?”
It took a bit of digging by the team, but we finally figured it out: It turns out that Sitecore does in fact put the very same code (with the IgnoreSerializableAttribute=true) in part of the Initialization Pipeline. Unfortunately, it’s one that you end up killing during the creation of a Delivery Server. Womp. :-/ Open up Sitecore.Cintel.dll and look for Sitecore.Cintel.Endpoint.Plumbing.InitializeRoutes. You’ll see the RegisterRoutes method has the following code:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = (IContractResolver) new DefaultContractResolver() { IgnoreSerializableAttribute = true, IgnoreSerializableInterface = true };
The pipeline patch looks like this:
<processor type="Sitecore.Cintel.Endpoint.Plumbing.InitializeRoutes, Sitecore.Cintel" patch:source="Sitecore.ExperienceProfile.config"/>
And if you check out Sitecore’s Guide to creating a Delivery Server, you’ll notice they specifically tell you to comment out that config file. *sad trombone*
With all that said, the process to get this out on your own is easy:
namespace Client.Framework.Processors { public class JsonFormatEnforcer { public void Process(PipelineArgs args) { var serializerSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings; var contractResolver = (DefaultContractResolver)serializerSettings.ContractResolver; contractResolver.IgnoreSerializableAttribute = true; } } }
Patch it in with a config and you’re good to go!