Let’s Talk

We would love to hear from you. Want to know more about
our services or have any questions? Say Hi!

What is Custom Field Serializer for NameValueList field in Sitecore Headless Services?

March 27, 2023
What is Custom Field Serializer for NameValueList field in Sitecore Headless Services?
Keyur Garala
Keyur Garala
Sitecore Certified Solutions Architect
what-is-custom-field-serializer-for-namevaluelist-field-in-sitecore-headless-services

All Sitecore Headless Service is about is JSON. To render the right content and get the best performance, you need the right JSON data.

Sitecore has some unique schema field serializers for the following field types:

  • Rich Text
  • Image
  • General Link
  • Date/Datetime
  • Checkbox
  • Links (Droplink, Droptree, Grouped Droplink)
  • Lists (Checklist, Multilist, TreeList and their variants)
  • Number
  • Integer
  • File
  • Default (Single-Line Text, Multi-Line Text and remaining field types)

Let’s talk about the NameValueList field. This field stores the value in the form of a query string that gets delivered as it already is in the layout service.

So, to get the data in a more structured way, we have to customize the Field Serializer for NameValueList.

Please follow the below given steps for changing the structure of the NameValueField:

Step 1 Create a custom serializer by inheriting Sitecore.LayoutService.Serialization.FieldSerializers.BaseFieldSerializer and overriding the WriteValue Method:

using Newtonsoft.Json; 
using Sitecore.Data.Fields; 
using Sitecore.Diagnostics; 
using Sitecore.Web.UI.WebControls; 
using System.Web; 
using System; 

public class NameValueListSerializer : BaseFieldSerializer 
{ 
    public NameValueListSerializer(IFieldRenderer fieldRenderer) : base(fieldRenderer) 
    { 

    } 
    protected override void WriteValue(Field field, JsonTextWriter writer) 
    { 
        Assert.ArgumentNotNull((object)field, nameof(field)); 
        Assert.ArgumentNotNull((object)writer, nameof(writer)); 
        try 
        { 
            writer.WriteStartObject(); 
            string range = field.Value; 
            if (!string.IsNullOrEmpty(range)) 
            { 
                string[] ranges = range.Split('&'); 
                if (ranges != null) 
                { 
                    foreach (string dropdownpair in ranges) 
                    { 
                        string[] pair = dropdownpair.Split('='); 
                        writer.WritePropertyName(pair[0]); 
                        writer.WriteValue(HttpUtility.UrlDecode(pair[1])); 
                    } 
                } 
            } 
            writer.WriteEndObject(); 
        } 
        catch (Exception ex) 
        { 
            Sitecore.Diagnostics.Log.Error(ex.Message, typeof(NameValueListSerializer)); 
        } 
    } 
} 
                        

Step 2 Implement the class by inheriting Sitecore.LayoutService.Serialization.Pipelines.GetFieldSerializer.BaseGetFieldSerializer and overriding the SetResult Method:

using Sitecore.Web.UI.WebControls; 
public class GetNameValueListSerializer : BaseGetFieldSerializer 
{ 
    public GetNameValueListSerializer(IFieldRenderer fieldRenderer) : base(fieldRenderer) 
    { 

    } 

    protected override void SetResult(GetFieldSerializerPipelineArgs args) 
    { 
        args.Result = (IFieldSerializer)new NameValueListSerializer(this.FieldRenderer); 
    } 
} 
                        

Step 3 Patch the custom resolver and make that it is patched before the GetDefaultFieldSerializer processor:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> 
  <sitecore> 
    <pipelines> 
      <group groupName="layoutService"> 
        <pipelines> 
          <getFieldSerializer> 
            <processor patch:before="processor[@type='Sitecore.LayoutService.Serialization.Pipelines.GetFieldSerializer.GetDefaultFieldSerializer, Sitecore.LayoutService']" type="Sandbox.GetNameValueListSerializer, Sandbox" resolve="true"> 
              <FieldTypes hint="list"> 
                <fieldType id="1">name value list</fieldType> 
              </FieldTypes> 
            </processor> 
          </getFieldSerializer> 
        </pipelines> 
      </group> 
    </pipelines> 
  </sitecore> 
</configuration> 
                        

We will get the object of the key-value pairs JSON response in the API instead of getting the query string.


YOU MAY ALSO LIKE