diff --git a/src/Framework/Framework/Compilation/ControlTree/ControlTreeResolverBase.cs b/src/Framework/Framework/Compilation/ControlTree/ControlTreeResolverBase.cs index bd1eae2fca..c435c02a7a 100644 --- a/src/Framework/Framework/Compilation/ControlTree/ControlTreeResolverBase.cs +++ b/src/Framework/Framework/Compilation/ControlTree/ControlTreeResolverBase.cs @@ -259,6 +259,10 @@ private IAbstractControl ProcessObjectElement(DothtmlElementNode element, IDataC constructorParameters = new[] { element.FullTagName }; element.AddError($"The control <{element.FullTagName}> could not be resolved! Make sure that the tagPrefix is registered in DotvvmConfiguration.Markup.Controls collection!"); } + if (controlMetadata.VirtualPath is {} && controlMetadata.Type.IsAssignableTo(ResolvedTypeDescriptor.Create(typeof(DotvvmView)))) + { + element.TagNameNode.AddWarning($"The markup control <{element.FullTagName}> has a baseType DotvvmView. Please make sure that the control file has .dotcontrol file extension. This will work, but causes unexpected issues, for example @js directive will not work in this control."); + } var control = treeBuilder.BuildControl(controlMetadata, element, dataContext); control.ConstructorParameters = constructorParameters; diff --git a/src/Tests/Runtime/ControlTree/DefaultControlTreeResolver/CompilationWarningsTests.cs b/src/Tests/Runtime/ControlTree/DefaultControlTreeResolver/CompilationWarningsTests.cs index cb512ab84e..a3c7c50f07 100644 --- a/src/Tests/Runtime/ControlTree/DefaultControlTreeResolver/CompilationWarningsTests.cs +++ b/src/Tests/Runtime/ControlTree/DefaultControlTreeResolver/CompilationWarningsTests.cs @@ -4,7 +4,11 @@ using DotVVM.Framework.Utils; using DotVVM.Framework.Controls; using DotVVM.Framework.Compilation.Parser.Dothtml.Parser; +using DotVVM.Framework.Testing; +using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualStudio.TestTools.UnitTesting; +using DotVVM.Framework.Hosting; +using DotVVM.Framework.Controls.Infrastructure; namespace DotVVM.Framework.Tests.Runtime.ControlTree @@ -100,6 +104,30 @@ @viewModel System.DateTime Assert.AreEqual(1, literal.DothtmlNode.NodeWarnings.Count()); Assert.AreEqual("Evaluation of method \"ToBrowserLocalTime\" on server-side may yield unexpected results.", literal.DothtmlNode.NodeWarnings.First()); } + + [TestMethod] + public void DefaultViewCompiler_DotvvmView_Used_As_Control_Warning() + { + var files = new FakeMarkupFileLoader(); + files.MarkupFiles["TestControl.dothtml"] = """ + @viewModel object + test + """; + var config = DotvvmTestHelper.CreateConfiguration(s => { + s.AddSingleton(files); + }); + config.Markup.AddMarkupControl("cc", "TestControl", "TestControl.dothtml"); + + var markup = DotvvmTestHelper.ParseResolvedTree(""" + @viewModel object + + """, configuration: config); + var control = markup.Content.SelectRecursively(c => c.Content).Single(c => c.Properties.ContainsKey(Styles.TagProperty)); + Assert.AreEqual(typeof(DotvvmView), control.Metadata.Type); + var element = (DothtmlElementNode)control.DothtmlNode; + XAssert.Contains("The markup control has a baseType DotvvmView", element.TagNameNode.NodeWarnings.First()); + Assert.AreEqual(1, element.TagNameNode.NodeWarnings.Count()); + } } }