DataType troubleshooting

This commit is contained in:
Stephan
2018-03-05 14:59:23 +01:00
parent 030c97ef26
commit 0277ddc584
11 changed files with 105 additions and 21 deletions

View File

@@ -27,7 +27,7 @@ namespace Umbraco.Core
/// <summary>
/// Color Picker.
/// </summary>
public const string ColorPicker = "Umbraco.ColorPickerAlias";
public const string ColorPicker = "Umbraco.ColorPicker";
/// <summary>
/// Content Picker.

View File

@@ -84,7 +84,7 @@ namespace Umbraco.Core.Migrations.Upgrade
.Chain<RefactorXmlColumns>("{3D18920C-E84D-405C-A06A-B7CEE52FE5DD}")
.Chain<VariantsMigration>("{FB0A5429-587E-4BD0-8A67-20F0E7E62FF7}")
.Chain<DropMigrationsTable>("{F0C42457-6A3B-4912-A7EA-F27ED85A2092}")
.Chain<RefactorDataType>("{8640C9E4-A1C0-4C59-99BB-609B4E604981}")
.Chain<DataTypeMigration>("{8640C9E4-A1C0-4C59-99BB-609B4E604981}")
.Chain<TagsMigration>("{DD1B99AF-8106-4E00-BAC7-A43003EA07F8}")
.Chain<SuperZero>("{CC1B1201-1328-443C-954A-E0BBB8CCC1B5}");
@@ -154,7 +154,7 @@ namespace Umbraco.Core.Migrations.Upgrade
// 8.0.0
Chain<VariantsMigration>("{6550C7E8-77B7-4DE3-9B58-E31C81CB9504}");
Chain<DropMigrationsTable>("{E3388F73-89FA-45FE-A539-C7FACC8D63DD}");
Chain<RefactorDataType>("{82C4BA1D-7720-46B1-BBD7-07F3F73800E6}");
Chain<DataTypeMigration>("{82C4BA1D-7720-46B1-BBD7-07F3F73800E6}");
Chain<TagsMigration>("{139F26D7-7E08-48E3-81D9-E50A21A72F67}");
Chain<SuperZero>("{CC1B1201-1328-443C-954A-E0BBB8CCC1B5}");
}

View File

@@ -1,20 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using Newtonsoft.Json;
using NPoco;
using Umbraco.Core.Migrations.Install;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
public class RefactorDataType : MigrationBase
public class DataTypeMigration : MigrationBase
{
public RefactorDataType(IMigrationContext context)
public DataTypeMigration(IMigrationContext context)
: base(context)
{ }
@@ -38,6 +37,12 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
foreach (var x in DatabaseSchemaCreator.OrderedTables)
Create.KeysAndIndexes(x.Value).Do();
// renames
Database.Execute(Sql()
.Update<DataTypeDto>(u => u.Set(x => x.EditorAlias, "Umbraco.ColorPicker"))
.Where<DataTypeDto>(x => x.EditorAlias == "Umbraco.ColorPickerAlias"));
// from preValues to configuration...
var sql = Sql()
.Select<DataTypeDto>()
.AndSelect<PreValueDto>(x => x.Alias, x => x.SortOrder, x => x.Value)
@@ -64,9 +69,9 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
}
else
{
// fixme deal with null or empty aliases
// fixme deal with duplicate aliases
// in these cases, fallback to array?
// assuming we don't want to fall back to array
if (aliases.Length != group.Count() || aliases.Any(string.IsNullOrWhiteSpace))
throw new InvalidOperationException($"Cannot migrate datatype w/ id={dataType.NodeId} preValues: duplicate or null/empty alias.");
// dictionary-base prevalues
var values = group.ToDictionary(x => x.Alias, x => x.Value);

View File

@@ -11,8 +11,9 @@
var exists = Database.Fetch<int>("select id from umbracoUser where id=-1;").Count > 0;
if (exists) return;
Database.Execute("set identity_insert umbracoUser on;");
Database.Execute("update umbracoUser set userLogin = userLogin + '__' where userId=0");
Database.Execute("set identity_insert umbracoUser on;");
Database.Execute(@"
insert into umbracoUser select -1,
userDisabled, userNoConsole, userName, substring(userLogin, 1, len(userLogin) - 2), userPassword, passwordConfig,
@@ -20,9 +21,12 @@
lastPasswordChangeDate, lastLoginDate, emailConfirmedDate, invitedDate,
createDate, updateDate, avatar
from umbracoUser where id=0;");
Database.Execute("update umbracoUser2UserGroup set userId=-1 where userId=0;");
Database.Execute("delete from umbracoUser where id=0;");
Database.Execute("set identity_insert umbracoUser off;");
Database.Execute("update umbracoUser2UserGroup set userId=-1 where userId=0;");
Database.Execute("update umbracoNode set nodeUser=-1 where nodeUser=0;");
Database.Execute("update uContentVersion set userId=-1 where userId=0;");
Database.Execute("delete from umbracoUser where id=0;");
}
}
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.PropertyEditors;
@@ -51,7 +53,7 @@ namespace Umbraco.Core.Persistence.Factories
EditorAlias = entity.EditorAlias,
NodeId = entity.Id,
DbType = entity.DatabaseType.ToString(),
Configuration = entity.Configuration == null ? null : JsonConvert.SerializeObject(entity.Configuration),
Configuration = entity.Configuration == null ? null : JsonConvert.SerializeObject(entity.Configuration, ConfigurationEditor.ConfigurationJsonSettings),
NodeDto = BuildNodeDto(entity)
};

View File

@@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Umbraco.Core.Serialization;
namespace Umbraco.Core.PropertyEditors
{
@@ -99,5 +102,35 @@ namespace Umbraco.Core.PropertyEditors
/// <inheritdoc />
public virtual Dictionary<string, object> ToValueEditor(object configuration)
=> ToConfigurationEditor(configuration);
/// <summary>
/// Gets the custom json serializer settings for configurations.
/// </summary>
public static JsonSerializerSettings ConfigurationJsonSettings { get; } = new JsonSerializerSettings
{
ContractResolver = new ConfigurationCustomContractResolver(),
Converters = new List<JsonConverter>(new[]{new FuzzyBooleanConverter()})
};
private class ConfigurationCustomContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
// base.CreateProperty deals with [JsonProperty("name")]
var property = base.CreateProperty(member, memberSerialization);
// override with our custom attribute, if any
var attribute = member.GetCustomAttribute<ConfigurationFieldAttribute>();
if (attribute != null) property.PropertyName = attribute.Key;
// for value types,
// don't try to deserialize nulls (in legacy json)
// no impact on serialization (value cannot be null)
if (member is PropertyInfo propertyInfo && propertyInfo.PropertyType.IsValueType)
property.NullValueHandling = NullValueHandling.Ignore;
return property;
}
}
}
}

View File

@@ -104,7 +104,7 @@ namespace Umbraco.Core.PropertyEditors
try
{
if (string.IsNullOrWhiteSpace(configuration)) return new TConfiguration();
return JsonConvert.DeserializeObject<TConfiguration>(configuration);
return JsonConvert.DeserializeObject<TConfiguration>(configuration, ConfigurationJsonSettings);
}
catch (Exception e)
{

View File

@@ -0,0 +1,42 @@
using System;
using Newtonsoft.Json;
namespace Umbraco.Core.Serialization
{
public class FuzzyBooleanConverter : JsonConverter
{
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException();
}
public override bool CanRead => true;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var value = reader.Value;
if (value is bool) return value;
switch (value.ToString().ToLower().Trim())
{
case "true":
case "yes":
case "y":
case "1":
return true;
case "false":
case "no":
case "n":
case "0":
return false;
}
return new JsonSerializer().Deserialize(reader, objectType);
}
public override bool CanConvert(Type objectType) => objectType == typeof(bool);
}
}

View File

@@ -314,7 +314,7 @@
<Compile Include="Constants.cs" />
<Compile Include="KeyValuePairExtensions.cs" />
<Compile Include="Migrations\MigrationBase_Extra.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\RefactorDataType.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypeMigration.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\SuperZero.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\TagsMigration.cs" />
<Compile Include="Models\ContentTagsExtensions.cs" />
@@ -1294,6 +1294,7 @@
<Compile Include="Serialization\JsonToStringConverter.cs" />
<Compile Include="Serialization\KnownTypeUdiJsonConverter.cs" />
<Compile Include="Serialization\NoTypeConverterJsonConverter.cs" />
<Compile Include="Serialization\FuzzyBooleanConverter.cs" />
<Compile Include="Serialization\SerializationExtensions.cs" />
<Compile Include="Serialization\SerializationService.cs" />
<Compile Include="Serialization\StreamedResult.cs" />

View File

@@ -36,7 +36,7 @@ namespace Umbraco.Web.Models.Mapping
/// </summary>
public IEnumerable<DataTypeConfigurationFieldDisplay> Resolve(IDataType dataType)
{
if (!string.IsNullOrWhiteSpace(dataType.EditorAlias) || !Current.PropertyEditors.TryGet(dataType.EditorAlias, out var e) || !(e is DataEditor editor))
if (string.IsNullOrWhiteSpace(dataType.EditorAlias) || !Current.PropertyEditors.TryGet(dataType.EditorAlias, out var e) || !(e is DataEditor editor))
throw new InvalidOperationException($"Could not find a property editor with alias \"{dataType.EditorAlias}\".");
var configuration = dataType.Configuration;

View File

@@ -18,15 +18,12 @@ namespace Umbraco.Web.PropertyEditors
public int? MaxItems { get; set; }
[ConfigurationField("confirmDeletes", "Confirm Deletes", "boolean", Description = "Set whether item deletions should require confirming.")]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // do not try to map a null value to a boolean
public bool ConfirmDeletes { get; set; } = true;
[ConfigurationField("showIcons", "Show Icons", "boolean", Description = "Set whether to show the items doc type icon in the list.")]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // do not try to map a null value to a boolean
public bool ShowIcons { get; set; } = true;
[ConfigurationField("hideLabel", "Hide Label", "boolean", Description = "Set whether to hide the editor label and have the list take up the full width of the editor window.")]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // do not try to map a null value to a boolean
public bool HideLabel { get; set; }
public class ContentType