Fixes: U4-3591 Creating PropertyValueConverter for a v7 prop editor (created with manifest) ends up with YSOD when outputting value on frontend

This commit is contained in:
Shannon
2013-11-21 16:39:21 +11:00
parent 4354840674
commit 6fd5eee4f6
4 changed files with 51 additions and 17 deletions

View File

@@ -82,24 +82,38 @@ namespace Umbraco.Core.Models.PublishedContent
{
var converters = PropertyValueConvertersResolver.Current.Converters.ToArray();
// todo: remove Union() once we drop IPropertyEditorValueConverter support.
_converter = null;
foreach (var converter in converters.Union(GetCompatConverters()).Where(x => x.IsConverter(this)))
{
if (_converter == null)
{
_converter = converter;
}
else
{
throw new InvalidOperationException(string.Format("Type '{2}' cannot be an IPropertyValueConverter"
+ " for property '{1}' of content type '{0}' because type '{3}' has already been detected as a converter"
+ " for that property, and only one converter can exist for a property.",
ContentType.Alias, PropertyTypeAlias,
converter.GetType().FullName, _converter.GetType().FullName));
}
}
var defaultConverters = converters
.Where(x => x.GetType().GetCustomAttribute<DefaultPropertyValueConverterAttribute>(false) != null)
.ToArray();
_converter = null;
//get all converters for this property type
// todo: remove Union() once we drop IPropertyEditorValueConverter support.
var foundConverters = converters.Union(GetCompatConverters()).Where(x => x.IsConverter(this)).ToArray();
if (foundConverters.Length == 1)
{
_converter = foundConverters[0];
}
else if (foundConverters.Length > 1)
{
//more than one was found, we need to first figure out if one of these is an Umbraco default value type converter
var nonDefault = foundConverters.Except(defaultConverters).ToArray();
if (nonDefault.Length > 1)
{
//this is not allowed, there cannot be more than 1 custom converter
throw new InvalidOperationException(
string.Format("Type '{2}' cannot be an IPropertyValueConverter"
+ " for property '{1}' of content type '{0}' because type '{3}' has already been detected as a converter"
+ " for that property, and only one converter can exist for a property.",
ContentType.Alias, PropertyTypeAlias,
nonDefault[1].GetType().FullName, nonDefault[0].GetType().FullName));
}
//there's only 1 custom converter registered that so use it
_converter = nonDefault[0];
}
// get the cache levels, quietely fixing the inconsistencies (no need to throw, really)
_sourceCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Source);
_objectCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Object);

View File

@@ -0,0 +1,12 @@
using System;
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Indicates that this is a default property value converter (shipped with Umbraco)
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
internal class DefaultPropertyValueConverterAttribute : Attribute
{
}
}

View File

@@ -6,6 +6,13 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
/// <summary>
/// The default converter for all property editors that expose a JSON value type
/// </summary>
/// <remarks>
/// Since this is a default (umbraco) converter it will be ignored if another converter found conflicts with this one.
/// </remarks>
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(JToken))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class JsonValueConverter : PropertyValueConverterBase

View File

@@ -331,6 +331,7 @@
<Compile Include="Models\TaggableObjectTypes.cs" />
<Compile Include="Models\TemplateNode.cs" />
<Compile Include="Packaging\PackageBinaryInspector.cs" />
<Compile Include="PropertyEditors\DefaultPropertyValueConverterAttribute.cs" />
<Compile Include="PropertyEditors\IValueEditor.cs" />
<Compile Include="PropertyEditors\PropertyCacheValue.cs" />
<Compile Include="PropertyEditors\PropertyValueCacheAttribute.cs" />