A custom validation attribute allows you to create metadata, that you can use in the data model to validate data fields. In order to validate when a collection is null or empty, you may create a custom validation attribute, which returns false in case the object is null or empty.
public class NotNullOrEmptyCollectionAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
var collection = value as ICollection;
if (collection != null)
{
return collection.Count != 0;
}
var enumerable = value as IEnumerable;
return enumerable != null && enumerable.GetEnumerator().MoveNext();
}
}
You can now decorate classes using this attribute, i.e.:
public class CustomModel
{
[NotNullOrEmptyCollection]
public IEnumerable<string> Recipients { get; set; }
}
Let’s assume that you have a WebAPI method `test/validation`, which:
- accepts an input of our CustomModel object
- returns this object if it’s valid
[AllowAnonymous, HttpPost, Route("validation")]
public IHttpActionResult TestCustomValidation(CustomModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
return Ok(model);
}
Responses on different input
Sending an empty object:
curl -X POST -H "Content-Type: application/json" -d '{}' "http://localhost:5000/api/test/validation"
Result:
{
"message": "The request is invalid.",
"modelState": {
"model.Recipients": [
"The field Recipients is invalid."
]
}
}
Sending an object with an empty `recipients` array:
curl -X POST -H "Content-Type: application/json" -d '{
"recipients": []
}' "http://localhost:5000/api/test/validation"
Result:
{
"message": "The request is invalid.",
"modelState": {
"model.Recipients": [
"The field Recipients is invalid."
]
}
}
Sending an object with an item in `recipients` array:
curl -X POST -H "Content-Type: application/json" -d '{
"recipients": ["test-recipient"]
}' "http://localhost:5000/api/test/validation"
Result:
{
"recipients": [
"test-recipient"
]
}