Search code examples
c#utf-8dynamics-crm-2015

Deserializing Settings Stored As JSON In CRM Web Resource


I've added some configuration data as JSON in a Web Resource in CRM. When I attempt to deserialize it in a C# plugin I have to first decode the Base 64 string, and then I have to encode the UTF bytes. I've done this before outside of CRM and haven't had an issue, but CRM threw me for a loop when my JSON wasn't deserializing due to an Argument Exception "Invalid JSON primitive: ."

I finally figured out that CRM includes the UTF Preamble and that isn't valid JSON so I have to remove it. Below is my current solution, but I would have thought there is a standard way to encode (or is it decode) the bytes that would check to see what the preamble was, and correctly apply the correct encoding and return the result without the preamble.

private static Settings Deserialize(WebResource value) {
    if (value == null)
    {
        throw new ArgumentNullException("value");
    }

    // By Default, Content is stored in a Base64String with a UTF preamble.
    var content = Encoding.UTF8.GetString(Convert.FromBase64String(value.Content)); 
    var preamble = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());

    if (content.StartsWith(preamble))
    {
        content = content.Remove(0, preamble.Length);
    }

    return new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Settings>(content); 
}

Surely there is a more standard way of doing this?


Solution

  • I dived into the Encoding Class structure and noticed that it takes a boolean encoderShouldEmitUTF8Identifier value to determine if the Preamble should be emitted. Unfortunately, the only thing this actually does is if set to false, the GetPreamble() will return an empty value. This means that you have to manually check for and remove the preamble if it exists.