Validate control usage
The controls in DotVVM can validate whether they are being used correctly. Simple checks can be done by using the MarkupOptions attribute, more complex validation logic is implemented in the ValidateUsage static method in the control code.
If control validation fails, the page will not compile, which is immediately visible in the compilation status page without the need to visit the page.
MarkupOptions attribute
The MarkupOptions attribute can be applied on DotVVM control properties and has several parameters which control how the property can be used:
Requiredindicates that the property must be set in the markup.AllowBindingindicates that the property can be bound-to on the client-side using value binding.AllowHardCodedValueindicates that the property can specify a value directly in the markup. This option also allows the resource binding which is not a client-side binding and is evaluated on the server.
ValidateUsage method
When some combination of control properties is not supported by a control, you can implement the necessary checks in a specific way in order to detect all errors on Status Page (API) and in the Visual Studio extension.
In the example below, we check whether control has either the Icon or Text property set.
[ControlUsageValidator]
public static IEnumerable<ControlUsageError> ValidateUsage(ResolvedControl control)
{
//Control usage checks
if (!control.HasProperty(IconProperty) && !control.HasProperty(TextProperty))
{
yield return new ControlUsageError("Button requires Icon, Text or both properties set.", control.DothtmlNode);
}
}
Warnings
Since DotVVM 4.3, the ValidateUsage method may also emit warnings, which are visible on the compilation status page and using the DotVVM CLI lint command.
Warning is emitted instead of an error if we add DiagnosticSeverity.Warning parameter in the constructor:
[ControlUsageValidator]
public static IEnumerable<ControlUsageError> ValidateUsage(ResolvedControl control)
{
if (control.Properties.ContainsKey(LabelProperty) && control.Properties.ContainsKey(SomeTemplateProperty))
{
var propertyNode = control.GetValue(LabelProperty).DothtmlNode;
yield return new("Label is ignored when SomeTemplate is also specified.", DiagnosticSeverity.Warning, propertyNode);
}
}