With data annotations, I think this is a good option, if you want to avoid third party. Skip required attributes and set the rule on a property that has a getter only:
public class EditModel
{
public string ISBN { get; set; }
public string ISBN13 { get; set; }
[Range(1, Double.MaxValue, ErrorMessage = "At least one field must be given a value")]
public int Count
{
get
{
var totalLength = 0;
totalLength += ISBN?.Length ?? 0;
totalLength += ISBN13?.Length ?? 0;
return totalLength;
}
}
}
For other data types, and with specific attributes, it works with something like this:
public class EditModel
{
[MinLength(10)]
public string ISBN { get; set; }
[MinLength(13)]
public string ISBN13 { get; set; }
[MinLength(1)]
public List<Guid> ISBNItems { get; set; }
[Range(1, 100)]
public int? SomeNumber { get; set; }
[Range(1, Double.MaxValue, ErrorMessage = "At least one field must be given a value")]
public int Count
{
get
{
var totalLength = 0;
totalLength += ISBN?.Length ?? 0;
totalLength += ISBN13?.Length ?? 0;
totalLength += ISBNItems?.Count ?? 0;
totalLength += SomeNumber ?? 0;
return totalLength;
}
}
}
Edit: I just thought of another way, where I replace the Count-property with this:
[RegularExpression("True|true", ErrorMessage = "At least one field must be given a value")]
public bool Any => ISBN != null || ISBN13 != null;
Basically, it's the same thing, just a getter that checks the properties are not null.