Description
Which exact Umbraco version are you using? For example: 8.7.0 - don't just write v8 or v9
13.5.2
Bug summary
Your implementation of PropertyValueConverterBase doesn't also implement IDeliveryApiPropertyValueConverter. I had to deregister yours in a composer and register a custom one.
Therefore UmbNav out of the box is incompatible with the Umbraco Content Delivery API.
Specifics
The value converter I used after I deregistered yours (I could have just extended yours if we used Serilogger but we don't so this made more sense for us):
public class CustomUmbNavValueConverter : PropertyValueConverterBase, IDeliveryApiPropertyValueConverter
{
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
private readonly IApiContentRouteBuilder _apiContentRouteBuilder;
private readonly ILogger<CustomUmbNavValueConverter> _logger;
private readonly IUmbNavMenuBuilderService _umbNavMenuBuilderService;
public CustomUmbNavValueConverter(
IPublishedSnapshotAccessor publishedSnapshotAccessor,
IApiContentRouteBuilder apiContentRouteBuilder,
ILogger<CustomUmbNavValueConverter> logger,
IUmbNavMenuBuilderService umbNavMenuBuilderService)
{
_publishedSnapshotAccessor = publishedSnapshotAccessor;
_apiContentRouteBuilder = apiContentRouteBuilder;
_logger = logger;
_umbNavMenuBuilderService = umbNavMenuBuilderService;
}
public override bool IsConverter(IPublishedPropertyType propertyType)
=> propertyType.EditorAlias.Equals("AaronSadler.UmbNav");
public override Type GetPropertyValueType(IPublishedPropertyType propertyType)
=> typeof(IEnumerable<UmbNavItem>);
public PropertyCacheLevel GetDeliveryApiPropertyCacheLevel(IPublishedPropertyType propertyType)
=> PropertyCacheLevel.Elements;
public PropertyCacheLevel GetDeliveryApiPropertyCacheLevelForExpansion(IPublishedPropertyType propertyType)
=> PropertyCacheLevel.Snapshot;
public Type GetDeliveryApiPropertyValueType(IPublishedPropertyType propertyType)
=> typeof(IEnumerable<UmbNavItem>);
public override object? ConvertIntermediateToObject(
IPublishedElement owner,
IPublishedPropertyType propertyType,
PropertyCacheLevel referenceCacheLevel,
object? inter,
bool preview)
{
if (inter is null)
{
_logger.LogWarning("No intermediate value found for property {PropertyAlias}.", propertyType.Alias);
return Enumerable.Empty<UmbNavItem>();
}
try
{
var items = JsonConvert.DeserializeObject<IEnumerable<UmbNavItem>>(inter.ToString() ?? string.Empty);
if (items == null)
{
_logger.LogWarning("Failed to deserialize UmbNav items for property {PropertyAlias}.", propertyType.Alias);
return Enumerable.Empty<UmbNavItem>();
}
// Build the menu using the UmbNavMenuBuilderService
var configuration = propertyType.DataType.ConfigurationAs<UmbNavConfiguration>();
if (configuration != null)
{
return _umbNavMenuBuilderService.BuildMenu(
items,
0,
configuration.RemoveNaviHideItems,
configuration.HideNoopener,
configuration.HideNoreferrer,
configuration.HideIncludeChildren,
configuration.AllowMenuItemDescriptions);
}
return items;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error converting UmbNav intermediate value for property {PropertyAlias}.", propertyType.Alias);
return Enumerable.Empty<UmbNavItem>();
}
}
public object? ConvertIntermediateToDeliveryApiObject(
IPublishedElement owner,
IPublishedPropertyType propertyType,
PropertyCacheLevel referenceCacheLevel,
object? inter,
bool preview,
bool expanding)
{
if (inter is null)
{
_logger.LogWarning("No intermediate value found for Delivery API conversion on property {PropertyAlias}.", propertyType.Alias);
return null;
}
try
{
var items = JsonConvert.DeserializeObject<IEnumerable<UmbNavItem>>(inter.ToString() ?? string.Empty);
if (items == null)
{
_logger.LogWarning("Failed to deserialize UmbNav items for Delivery API on property {PropertyAlias}.", propertyType.Alias);
return null;
}
return items;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error converting UmbNav intermediate value for Delivery API on property {PropertyAlias}.", propertyType.Alias);
return null;
}
}
}
Steps to reproduce
Set up the umbraco content delivery api
Create a Doc Type that uses navigation
Create content using that doc type
Try to return that content via the content delivery api
Expected result / actual result
I expected to receive usable content
What I got instead was an alternating experience between a 500 error and content stuck in a recursive loop (the json ignore attribute on content in class UmbNavItem is not recognized by the content delivery api because your class, UmbNavValueConverter
only extends PropertyValueConverterBase
but does not also implement IDeliveryApiPropertyValueConverter
)
I do not know why sometimes I got the 500 error and sometimes I got the content stuck in a recursive loop but here's an example of one of the times I got content:
"headerNavigation":[{"udi":{"guid":"4edaad94-029e-43d3-ba74-75cffea28c7a","isRoot":false,"uriValue":"umb://document/4edaad94029e43d3ba7475cffea28c7a","entityType":"document"},"key":"4edaad94-029e-43d3-ba74-75cffea28c7a","name":"Home","title":"Home","description":null,"target":null,"noopener":null,"noreferrer":null,"anchor":null,"children":[],"parent":null,"content":{"id":1128,"name":"Home","urlSegment":"home","sortOrder":0,"level":1,"path":"-1,1128","templateId":null,"creatorId":1,"createDate":"2024-11-05T19:37:14.247Z","writerId":1,"updateDate":"2024-11-25T10:55:56.04Z","cultures":{"":{"culture":"","name":"Home","urlSegment":"home","date":"2024-11-05T19:37:14.247Z"}},"itemType":"Content","parent":null,"children":[{"id":1145,"name":"Test Page","urlSegment":"test-page","sortOrder":0,"level":2,"path":"-1,1128,1145","templateId":null,"creatorId":1,"createDate":"2024-11-25T10:39:20.907Z","writerId":1,"updateDate":"2024-11-25T10:39:20.907Z","cultures":{"":{"culture":"","name":"Test Page","urlSegment":"test-page","date":"2024-11-25T10:39:20.907Z"}},"itemType":"Content","parent":{"id":1128,"name":"Home","urlSegment":"home","sortOrder":0,"level":1,"path":"-1,1128","templateId":null,"creatorId":1,"createDate":"2024-11-05T19:37:14.247Z","writerId":1,"updateDate":"2024-11-25T10:55:56.04Z","cultures":{"":{"culture":"","name":"Home","urlSegment":"home","date":"2024-11-05T19:37:14.247Z"}},"itemType":"Content","parent":null,"children":[{"id":1145,"name":"Test Page","urlSegment":"test-page","sortOrder":0,"level":2,"path":"-1,1128,1145","templateId":null,"creatorId":1,"createDate":"2024-11-25T10:39:20.907Z","writerId":1,"updateDate":"2024-11-25T10:39:20.907Z","cultures":{"":{"culture":"","name":"Test Page","urlSegment":"test-page","date":"2024-11-25T10:39:20.907Z"}},"itemType":"Content","parent":{"id":1128,"name":"Home","urlSegment":"home","sortOrder":0,"level":1,"path":"-1,1128","templateId":null,"creatorId":1,"createDate":"2024-11-05T19:37:14.247Z","writerId":1,"updateDate":"2024-11-25T10:55:56.04Z","cultures":{"":{"culture":"","name":"Home","urlSegment":"home","date":"2024-11-05T19:37:14.247Z"}},"itemType":"Content","parent":null,"children":[{"id":1145,"name":"Test Page","urlSegment":"test-page","sortOrder":0,"level":2,"path":"-1,1128,1145","templateId":null,"creatorId":1,"createDate":"2024-11-25T10:39:20.907Z","writerId":1,"updateDate":"2024-11-25T10:39:20.907Z","cultures":{"":{"culture":"","name":"Test Page","urlSegment":"test-page","date":"2024-11-25T10:39:20.907Z"}},"itemType":"Content","parent":{"id":1128,"name":"Home","urlSegment":"home","sortOrder":0,"level":1,"path":"-1,1128","templateId":null,"creatorId":1,"createDate":"2024-11-05T19:37:14.247Z","writerId":1,"updateDate":"2024-11-25T10:55:56.04Z","cultures":{"":{"culture":"","name":"Home","urlSegment":"home","date":"2024-11-05T19:37:14.247Z"}},"itemType":"Content","parent":null,"children":[{"id":1145,"name":"Test Page","urlSegment":"test-page","sortOrder":0,"level":2,"path":"-1,1128,1145","templateId":null,"creatorId":1,"createDate":"2024-11-25T10:39:20.907Z","writerId":1,"updateDate":"2024-11-25T10:39:20.907Z","cultures":{"":{"culture":"","name":"Test Page","urlSegment":"test-page","date":"2024-11-25T10:39:20.907Z"}},"itemType":"Content","parent":{"id":1128,"name":"Home","urlSegment":"home","sortOrder":0,"level":1,"path":"-1,1128","templateId":null,"creatorId":1,"createDate":"2024-11-05T19:37:14.247Z","writerId":1,"updateDate":"2024-11-25T10:55:56.04Z","cultures":{"":{"culture":"","name":"Home","urlSegment":"home","date":"2024-11-05T19:37:14.247Z"}},"itemType":"Content","parent":null,"children":[{"id":1145,"name":"Test Page","urlSegment":"test-page","sortOrder":0,"level":2,"path":"-1,1128,1145","templateId":null,"creatorId":1,"createDate":"2024-11-25T10:39:20.907Z","writerId":1,"updateDate":"2024-11-25T10:39:20.907Z","cultures":{"":{"culture":"","name":"Test Page","urlSegment":"test-page","date":"2024-11-25T10:39:20.907Z"}},"itemType":"Content","parent":{"id":1128,"name":"Home","urlSegment":"home","sortOrder":0,"level":1,"path":"-1,1128","templateId":null,"creatorId":1,"createDate":"2024-11-05T19:37:14.247Z","writerId":1,"updateDate":"2024-11-25T10:55:56.04Z","cultures":{"":{"culture":"","name":"Home","urlSegment":"home","date":"2024-11-05T19:37:14.247Z"}},"itemType":"Content","parent":null,"children":[{"id":1145,"name":"Test Page","urlSegment":"test-page","sortOrder":0,"level":2,"path":"-1,1128,1145","templateId":null,"creatorId":1,"createDate":"2024-11-25T10:39:20.907Z","writerId":1,"updateDate":"2024-11-25T10:39:20.907Z","cultures":{"":{"culture":"","name":"Test Page","urlSegment":"test-page","date":"2024-11-25T10:39:20.907Z"}},"itemType":"Content","parent":{"id":1128,"name":"Home","urlSegment":"home","sortOrder":0,"level":1,"path":"-1,1128","templateId":null,"creatorId":1,"createDate":"2024-11-05T19:37:14.247Z","writerId":1,"updateDate":"2024-11-25T10:55:56.04Z","cultures":{"":{"culture":"","name":"Home","urlSegment":"home","date":"2024-11-05T19:37:14.247Z"}},"itemType":"Content","parent":null,"children":[{"id":1145,"name":"Test Page","urlSegment":"test-page","sortOrder":0,"level":2,"path":"-1,1128,1145","templateId":null,"creatorId":1,"createDate":"2024-11-25T10:39:20.907Z","writerId":1,"updateDate":"2024-11-25T10:39:20.907Z","cultures":{"":{"culture":"","name":"Test Page","urlSegment":"test-page","date":"2024-11-25T10:39:20.907Z"}},"itemType":"Content","parent":{"id":1128,"name":"Home","urlSegment":"home","sortOrder":0,"level":1,"path":"-1,1128","templateId":null,"creatorId":1,"createDate":"2024-11-05T19:37:14.247Z","writerId":1,"updateDate":"2024-11-25T10:55:56.04Z","cultures":{"":{"culture":"","name":"Home","urlSegment":"home","date":"2024-11-05T19:37:14.247Z"}},"itemType":"Content","parent":null,"children":[{"id":1145,"name":"Test Page","urlSegment":"test-page","sortOrder":0,"level":2,"path":"-1,1128,1145","templateId":null,"creatorId":1,"createDate":"2024-11-25T10:39:20.907Z","writerId":1,"updateDate":"2024-11-25T10:39:20.907Z","cultures":{"":{"culture":"","name":"Test Page","urlSegment":"test-page","date":"2024-11-25T10:39:20.907Z"}}
There's no end to this because it was stuck in a recursive loop