.Net 8 JsonSerializer IContent Object and anyone who is using this JsonSerializer.Serialize method in your solution

Vote:
 

Running on EpiSever.CMS 12.31.2 

Recently we move the solution .net8 but facing issues when using the below code snippet:

var jsonSerializeSettings = new JsonSerializerOptions
{
WriteIndented = true,
ReferenceHandler = ReferenceHandler.IgnoreCycles,
};
 
string objSerializedString = JsonSerializer.Serialize(content, jsonSerializeSettings);
 
The exception, we are seeing:
Serialization and deserialization of 'System.Type' instances is not supported. Path: $.Property.PropertyValueType.
 ---> System.NotSupportedException: Serialization and deserialization of 'System.Type' instances is not supported.
 
If we add a custom Converter to write down the assebly name, then we are seeing the exception: System.NotSupportedException: 'Serialization and deserialization of 'EPiServer.ServiceLocation.ServiceAccessor`1[[EPiServer.Core.Internal.ContentFragmentFactory, EPiServer, Version=12.22.0.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7]]' instances is not supported. The unsupported member type is located on type 'EPiServer.ServiceLocation.ServiceAccessor`1[EPiServer.Core.Internal.ContentFragmentFactory]'. Path: $.Property.Value.FragmentFactory.Accessor.'
 
We attempted to use NewtonSoft.Json to serialize the object, but we found that performance degraded rapidly, and the server was unable to handle the requests after timing out.
#335344
Edited, Jan 08, 2025 20:30
Vote:
 

Did it work in .net6?

I don't think that if you serialize this way the serializer will use our registered converters and options.

You should resolve our options with converters and use them:

var options = ServiceLocator.Current.GetInstance<SystemTextJsonSettingsOptions>();
var jsonSerializerOptions = options.SerializerOptions.JsonSerializerOptions;
//your custom settings
jsonSerializerOptions.WriteIndented = true;
//your custom settings
var jsonString = JsonSerializer.Serialize(content, options.SerializerOptions.JsonSerializerOptions);

But I'm not sure if that way all your properties will be properly serialized.

I would advice to use this little class:

[ServiceConfiguration]
public class SimpleIContentSerializer
{
    private readonly IContentStoreModelCreator _contentStoreModelCreator;
    private readonly IObjectSerializer _objectSerializer;

    public SimpleIContentSerializer(IContentStoreModelCreator contentStoreModelCreator, IObjectSerializer objectSerializer)
    {
        _contentStoreModelCreator = contentStoreModelCreator;
        _objectSerializer = objectSerializer;
    }

    public string Serialize(IContent content)
    {
        var queryParameters = new DefaultQueryParameters
        {
            TypeIdentifiers = Enumerable.Empty<string>(),
            AllParameters = new NameValueCollection()
        };

        var creator = _contentStoreModelCreator.CreateContentDataStoreModel<ContentDataStoreModel>(content, queryParameters);

        return _objectSerializer.Serialize(creator);
    }
}

I don't know what exactly did you need from your IContent content object but the code above will give you all the properties and some additional stuff.

Probably it would also work if you just used our IObjectSerializer, unless you have newtonsoft converters in your codebase.

#335514
Jan 12, 2025 19:17
Vote:
 

Thanks for the reply. 

The snippet was working on .net 6 (with EPiServer.CMS.Core 12.21.7, EPiServer.ContentDeliveryApi.Cms 3.11.3).

I will get it a try using your suggestion. 

 

#335566
Jan 13, 2025 15:49
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.