diff --git a/src/Framework/Framework/Binding/ConstantDataContextChangeAttribute.cs b/src/Framework/Framework/Binding/ConstantDataContextChangeAttribute.cs index fe69276cb7..7b4b91c840 100644 --- a/src/Framework/Framework/Binding/ConstantDataContextChangeAttribute.cs +++ b/src/Framework/Framework/Binding/ConstantDataContextChangeAttribute.cs @@ -17,13 +17,20 @@ public class ConstantDataContextChangeAttribute : DataContextChangeAttribute public override int Order { get; } public bool? ServerSideOnly { get; } - public ConstantDataContextChangeAttribute(Type type, int order = 0, bool? serverSideOnly = null) + public ConstantDataContextChangeAttribute(Type type, int order = 0) + { + Type = type; + Order = order; + ServerSideOnly = null; + } + + public ConstantDataContextChangeAttribute(Type type, int order, bool serverSideOnly) { Type = type; Order = order; ServerSideOnly = serverSideOnly; } - + public override ITypeDescriptor? GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor? property = null) { return new ResolvedTypeDescriptor(Type); diff --git a/src/Framework/Framework/Configuration/DefaultSerializerSettingsProvider.cs b/src/Framework/Framework/Configuration/DefaultSerializerSettingsProvider.cs index 4004e4ddd4..97c5ea3275 100644 --- a/src/Framework/Framework/Configuration/DefaultSerializerSettingsProvider.cs +++ b/src/Framework/Framework/Configuration/DefaultSerializerSettingsProvider.cs @@ -14,8 +14,8 @@ namespace DotVVM.Framework.Configuration public sealed class DefaultSerializerSettingsProvider { private const int defaultMaxSerializationDepth = 64; - internal readonly JsonSerializerOptions SettingsHtmlUnsafe; - internal readonly JsonSerializerOptions Settings; + public readonly JsonSerializerOptions SettingsHtmlUnsafe; + public readonly JsonSerializerOptions Settings; // We need to encode for script tags (i.e. either < or / has to go) and for HTML comments (< and > have to go - https://html.spec.whatwg.org/#comments) // The default JavaScriptEncoder is just annoyingly paranoid, I'm not interested in having all non-ASCII characters escaped to unicode codepoints @@ -25,7 +25,7 @@ public sealed class DefaultSerializerSettingsProvider // https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#prod-DoubleStringCharacter // - it says « SourceCharacter [=any Unicode code point] but not one of " or \ or LineTerminator » // ...which isn't allowed in JSON in any context anyway - internal readonly JavaScriptEncoder HtmlSafeLessParanoidEncoder; + public readonly JavaScriptEncoder HtmlSafeLessParanoidEncoder; private JsonSerializerOptions CreateSettings() { diff --git a/src/Framework/Framework/Controls/DotvvmBindableObject.cs b/src/Framework/Framework/Controls/DotvvmBindableObject.cs index 544653080d..b42b8e20db 100644 --- a/src/Framework/Framework/Controls/DotvvmBindableObject.cs +++ b/src/Framework/Framework/Controls/DotvvmBindableObject.cs @@ -13,7 +13,6 @@ namespace DotVVM.Framework.Controls [ContainsDotvvmProperties] [ControlMarkupOptions(AllowContent = true)] - [System.Text.Json.Serialization.JsonConverter(typeof(DotvvmControlDebugJsonConverter))] public abstract class DotvvmBindableObject: IDotvvmObjectLike { diff --git a/src/Framework/Framework/Controls/DotvvmControlDebugJsonConverter.cs b/src/Framework/Framework/Controls/DotvvmControlDebugJsonConverter.cs index 251186ab2b..4e48f3fd9d 100644 --- a/src/Framework/Framework/Controls/DotvvmControlDebugJsonConverter.cs +++ b/src/Framework/Framework/Controls/DotvvmControlDebugJsonConverter.cs @@ -29,7 +29,15 @@ internal class DotvvmControlDebugJsonConverter() : GenericWriterJsonConverter Returns itself. This is a kinda hack which allows interfaces to inherit from almost DotvvmBindableObject + [JsonIgnore] DotvvmBindableObject Self { get; } } /// Marker interface for DotvvmBindableObject which have the specified capability. If no capability of type TCapability is defined, it will be registered automatically. diff --git a/src/Framework/Framework/Hosting/ErrorPages/ErrorPageTemplate.cs b/src/Framework/Framework/Hosting/ErrorPages/ErrorPageTemplate.cs index e336b79c94..26c7617c61 100644 --- a/src/Framework/Framework/Hosting/ErrorPages/ErrorPageTemplate.cs +++ b/src/Framework/Framework/Hosting/ErrorPages/ErrorPageTemplate.cs @@ -165,6 +165,7 @@ internal static JsonNode SerializeObjectForBrowser(object? obj) Converters = { new DebugReflectionTypeJsonConverter(), new ReflectionAssemblyJsonConverter(), + new ReflectionTypeJsonConverter(), new DotvvmTypeDescriptorJsonConverter(), new Controls.DotvvmControlDebugJsonConverter(), new BindingDebugJsonConverter(), diff --git a/src/Framework/Framework/ResourceManagement/ReflectionAssemblyJsonConverter.cs b/src/Framework/Framework/ResourceManagement/ReflectionAssemblyJsonConverter.cs index 8cebd81729..fb15b9882d 100644 --- a/src/Framework/Framework/ResourceManagement/ReflectionAssemblyJsonConverter.cs +++ b/src/Framework/Framework/ResourceManagement/ReflectionAssemblyJsonConverter.cs @@ -8,6 +8,7 @@ using System.Reflection; using System.Text.Json; using System.Text.Json.Serialization; +using DotVVM.Framework.Utils; namespace DotVVM.Framework.ResourceManagement { @@ -15,11 +16,7 @@ public class ReflectionAssemblyJsonConverter : JsonConverter { public override Assembly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - if (reader.TokenType == JsonTokenType.String) - { - return Assembly.Load(new AssemblyName(reader.GetString()!)); - } - else throw new NotSupportedException(); + throw new NotSupportedException(); } public override void Write(Utf8JsonWriter writer, Assembly value, JsonSerializerOptions options) @@ -32,12 +29,7 @@ public class ReflectionTypeJsonConverter : JsonConverter { public override Type Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - if (reader.TokenType == JsonTokenType.String) - { - var name = reader.GetString()!; - return Type.GetType(name) ?? throw new Exception($"Cannot find type {name}."); - } - else throw new NotSupportedException(); + throw new NotSupportedException(); } public override void Write(Utf8JsonWriter writer, Type t, JsonSerializerOptions options) @@ -62,15 +54,7 @@ public class DotvvmTypeDescriptorJsonConverter : JsonConverter { public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - if (reader.TokenType == JsonTokenType.String) - { - var name = reader.GetString()!; - ITypeDescriptor result = new ResolvedTypeDescriptor(Type.GetType(name) ?? throw new Exception($"Cannot find type {name}.")); - if (result is T t) - return t; - else throw new NotSupportedException($"Cannot deserialize {typeToConvert}"); - } - else throw new NotSupportedException(); + throw new NotSupportedException(); } public override void Write(Utf8JsonWriter writer, T t, JsonSerializerOptions options) @@ -105,7 +89,15 @@ internal static void WriteObjectReflection(Utf8JsonWriter writer, object attribu writer.WritePropertyName(prop.Name); - JsonSerializer.Serialize(writer, prop.GetValue(attribute), options); + var value = prop.GetValue(attribute); + + // NB: RuntimeType is internal, so we need to use first public base type + var valueType = value?.GetType() ?? typeof(object); + while (!valueType.IsPublicType() || valueType == typeof(TypeInfo)) + { + valueType = valueType.BaseType!; + } + JsonSerializer.Serialize(writer, value, valueType, options); } writer.WriteEndObject(); }