I found a way to build a custom attribute that checks gives an error if any other values than the required block property is set. So in my case, if for instance an editor enters a value for Image Description and tries to publish without specifying an ImageUrl, an errormessage will show.
The code looks like this:
public class RequiredBlockPropertyAttribute : ValidationAttribute
{
private string _failedOnProperty = string.Empty;
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return ValidateBlock(value, validationContext)
? ValidationResult.Success
: new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
private bool ValidateBlock(object value, ValidationContext validationContext)
{
var type = validationContext.ObjectType.BaseType;
if (type == null)
return true;
var properties = type.GetProperties().Where(prop =>
prop.DeclaringType != null
&& prop.DeclaringType.IsSubclassOf(typeof(BlockData)));
foreach (var property in properties)
{
if (!property.Name.Equals(validationContext.DisplayName))
{
var val = property.GetValue(validationContext.ObjectInstance, null);
if (val != null && (value == null || IsDateTimeMinValue(value)))
{
_failedOnProperty = property.Name;
return false;
}
}
}
return true;
}
private static bool IsDateTimeMinValue(object value)
{
DateTime t;
DateTime.TryParse(value.ToString(), out t);
return t == DateTime.MinValue;
}
public override string FormatErrorMessage(string name)
{
return string.Format(ErrorMessageString, name, _failedOnProperty);
}
And the usage in the block:
[RequiredBlockProperty(
ErrorMessage = "{1} cannot be set without {0} defined")]
[UIHint(UIHint.Image)]
[Display(
Name = "Image Url",
Description = "",
GroupName = SystemTabNames.Content,
Order = 10)]
public virtual Url ImageUrl { get; set; }