Getting EPiServer 6 custom properties to work in EPiServer 7: Cannot create and populate list type…
When working on getting EPiImage to work in EPiServer 7 I ran into the following error when publishing or auto saving an EPiImageGalleryProperty.
From the error message I guessed it had something to do with the JSON communication used in the new UI.
Turns out that since EPiImageGalleryProperty stores its data as an EPiImageGalleryImageCollection object, EPiServer 7 doesn’t know how to serialize it as a JSON object. But how can we tell EPiServer explicitly how to do the serialization?
Luckily Linus Ekström (EPiServer Sweden) helped me out with some sample code:
using System;
using EPiServer.ServiceLocation;
using Newtonsoft.Json;
namespace EPiServer.Cms.Shell.Json
{
/// <summary>
/// Json converter thas handles conversion between
/// <see cref="Url"/> and <see cref="string"/>.
/// </summary>
[ServiceConfiguration(typeof(JsonConverter))]
public class UrlConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Url).IsAssignableFrom(objectType);
}
public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
return (reader.Value == null) ? null :
new Url(reader.Value.ToString());
}
public override void WriteJson(
JsonWriter writer,
object value,
JsonSerializer serializer)
{
var url = value as Url;
if (url == null || url.IsEmpty())
{
writer.WriteValue(string.Empty);
return;
}
writer.WriteValue(value.ToString());
}
}
}
This class which inherits from JsonConverter tells EPiServer 7 how to do the conversion of a EPiServer.Url to Json (meaning a string representation) and back again.
I can create my own Json converter for EPiImageGalleryImageCollection like this:
using System;
using EPiServer.ServiceLocation;
using Newtonsoft.Json;
namespace MakingWaves.EPiImage.EPiImage.Code
{
/// <summary>
/// Json converter that handles conversion between
/// EPiImageGalleryImageCollectionConverter
/// and string for the new EPiServer 7 UI
/// </summary>
[ServiceConfiguration(typeof(JsonConverter))]
public class EPiImageGalleryImageCollectionJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(EPiImageGalleryImageCollection).IsAssignableFrom(objectType);
}
public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
if (reader.Value == null)
return null;
return new EPiImageGalleryImageCollection(reader.Value.ToString());
}
public override void WriteJson(
JsonWriter writer,
object value,
JsonSerializer serializer)
{
EPiImageGalleryImageCollection gallery = value
as EPiImageGalleryImageCollection;
if (gallery == null || gallery.Count == 0)
{
writer.WriteValue(string.Empty);
return;
}
writer.WriteValue(gallery.ToString());
}
}
}
For it to work I also needed to do the following changes to my existing EPiImage code:
1. Create a ToString method for EPiImageGalleryImageCollection that accurately serialized the data in the object to a string. As it consists of a List<EPiImageGalleryImage> I also need to:
2. Create a ToString method for EPiImageGalleryImage that accurately serialized the data in the object to a string
3. Create a constructor method for EPiImageGalleryImageCollection that could take in the serialized string as a parameter to recreate the object
4. Create a constructor method for EPiImageGalleryImage that could take in the serialized string as a parameter to recreate the object
If you are converting your own custom property to work with EPiServer 7, I thought this code might guide you in the right direction
Comments