Skip to content

Commit

Permalink
Validate that properties on custom primitive types are not used in JS
Browse files Browse the repository at this point in the history
The primitive will be a string client-side, and the property
will thus always be `undefined`.
  • Loading branch information
exyi committed Sep 24, 2023
1 parent ba2db14 commit 05029b0
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions src/Tests/Binding/JavascriptCompilationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<NotSupportedException>(() => CompileBinding("VehicleNumber.Value.Value", typeof(TestViewModel)));
XAssert.Contains("Cannot translate property Value on custom primitive type DotVVM.Framework.Tests.Binding.VehicleNumber", e.Message);
}

[TestMethod]
Expand Down

0 comments on commit 05029b0

Please sign in to comment.