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:
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.