diff --git a/src/Framework/Framework/Compilation/Javascript/JsViewModelPropertyAdjuster.cs b/src/Framework/Framework/Compilation/Javascript/JsViewModelPropertyAdjuster.cs index e340683b59..1cc6a40fc1 100644 --- a/src/Framework/Framework/Compilation/Javascript/JsViewModelPropertyAdjuster.cs +++ b/src/Framework/Framework/Compilation/Javascript/JsViewModelPropertyAdjuster.cs @@ -10,7 +10,9 @@ using DotVVM.Framework.Compilation.Javascript.Ast; using DotVVM.Framework.Controls; using DotVVM.Framework.Utils; +using DotVVM.Framework.ViewModel; using DotVVM.Framework.ViewModel.Serialization; +using FastExpressionCompiler; namespace DotVVM.Framework.Compilation.Javascript { @@ -92,6 +94,11 @@ member is {} && throw new NotSupportedException($"Control property {member.Name} is not a registered DotvvmProperty and cannot be used client-side. Either use a resource binding to use the server-side value, or see https://www.dotvvm.com/docs/latest/pages/concepts/control-development/control-properties how to register a DotvvmProperty."); } + if (member is {} && typeof(IDotvvmPrimitiveType).IsAssignableFrom(member.DeclaringType)) + { + throw new NotSupportedException($"Cannot translate property {member.Name} on custom primitive type {member.DeclaringType.ToCode()} to Javascript. Use the ToString() method to get the underlying value."); + } + annotation.ContainsObservables ??= !this.preferUsingState; // we don't know -> guess what is the current preference if (annotation.ContainsObservables == true) diff --git a/src/Tests/Binding/JavascriptCompilationTests.cs b/src/Tests/Binding/JavascriptCompilationTests.cs index fde904b7e6..1e17b26a28 100644 --- a/src/Tests/Binding/JavascriptCompilationTests.cs +++ b/src/Tests/Binding/JavascriptCompilationTests.cs @@ -1309,6 +1309,16 @@ public void JavascriptCompilation_CustomPrimitiveToString() { var result = CompileBinding("VehicleNumber.ToString()", typeof(TestViewModel)); Assert.AreEqual("VehicleNumber", result); + // nullable .Value unwrap + result = CompileBinding("VehicleNumber.Value.ToString()", typeof(TestViewModel)); + Assert.AreEqual("VehicleNumber", result); + } + + [TestMethod] + public void JavascriptCompilation_CustomPrimitiveProperty_Disallowed() + { + var e = Assert.ThrowsException(() => CompileBinding("VehicleNumber.Value.Value", typeof(TestViewModel))); + XAssert.Contains("Cannot translate property Value on custom primitive type DotVVM.Framework.Tests.Binding.VehicleNumber", e.Message); } [TestMethod]