Validation system is used to validate the user input or client request for a particular controller action or service method.
ABP is compatible with the ASP.NET Core Model Validation system and everything written in its documentation is already valid for ABP based applications. So, this document mostly focuses on the ABP features rather than repeating the Microsoft documentation.
In addition, ABP adds the following benefits:
IValidationEnabled
to add automatic validation to an arbitrary class. Since all the application services inherently implements it, they are also validated automatically.This section briefly introduces the validation system. For details, see the ASP.NET Core validation documentation.
Data Annotation AttributesUsing data annotations is a simple way to implement the formal validation for a DTO in a declarative way. Example:
public class CreateBookDto
{
[Required]
[StringLength(100)]
public string Name { get; set; }
[Required]
[StringLength(1000)]
public string Description { get; set; }
[Range(0, 999.99)]
public decimal Price { get; set; }
}
When you use this class as a parameter to an application service or a controller, it is automatically validated and a localized validation exception is thrown (and handled by the ABP).
IValidatableObjectIValidatableObject
can be implemented by a DTO to perform custom validation logic. CreateBookDto
in the following example implements this interface and checks if the Name
is equals to the Description
and returns a validation error in this case.
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Acme.BookStore
{
public class CreateBookDto : IValidatableObject
{
[Required]
[StringLength(100)]
public string Name { get; set; }
[Required]
[StringLength(1000)]
public string Description { get; set; }
[Range(0, 999.99)]
public decimal Price { get; set; }
public IEnumerable<ValidationResult> Validate(
ValidationContext validationContext)
{
if (Name == Description)
{
yield return new ValidationResult(
"Name and Description can not be the same!",
new[] { "Name", "Description" }
);
}
}
}
}
Resolving a Service
If you need to resolve a service from the dependency injection system, you can use the ValidationContext
object. Example:
var myService = validationContext.GetRequiredService<IMyService>();
Validation InfrastructureWhile resolving services in the
Validate
method allows any possibility, it is not a good practice to implement your domain validation logic in DTOs. Keep DTOs simple. Their purpose is to transfer data (DTO: Data Transfer Object).
This section explains a few additional services provided by the ABP.
IValidationEnabled InterfaceIValidationEnabled
is an empty marker interface that can be implemented by any class (registered to and resolved from the DI) to let the ABP perform the validation system for the methods of the class. Example:
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Validation;
namespace Acme.BookStore
{
public class MyService : ITransientDependency, IValidationEnabled
{
public virtual async Task DoItAsync(MyInput input)
{
//...
}
}
}
Enabling/Disabling ValidationABP uses the dynamic proxying / interception system to perform the validation. In order to make it working, your method should be virtual or your service should be injected and used over an interface (like
IMyService
).
You can use the [DisableValidation]
to disable it for methods, classs and properties.
[DisableValidation]
public Void MyMethod()
{
}
[DisableValidation]
public class InputClass
{
public string MyProperty { get; set; }
}
public class InputClass
{
[DisableValidation]
public string MyProperty { get; set; }
}
AbpValidationException
Once ABP determines a validation error, it throws an exception of type AbpValidationException
. Your application code can throw AbpValidationException
, but most of the times it is not needed.
ValidationErrors
property of the AbpValidationException
contains the validation error list.AbpValidationException
is set to Warning
. It logs all the validation errors to the logging system.AbpValidationException
is automatically caught by the ABP and converted to a usable error into with HTTP 400 status code. See the exception handling document for more.In addition to the automatic validation, you may want to manually validate an object. In this case, inject and use the IObjectValidator
service:
ValidateAsync
method validates the given object based on the validation rules and throws an AbpValidationException
if it is not in a valid state.GetErrorsAsync
doesn't throw an exception, but only returns the validation errors.IObjectValidator
is implemented by the ObjectValidator
by default. ObjectValidator
is extensible; you can implement IObjectValidationContributor
interface to contribute a custom logic. Example:
public class MyObjectValidationContributor
: IObjectValidationContributor, ITransientDependency
{
public Task AddErrorsAsync(ObjectValidationContext context)
{
//Get the validating object
var obj = context.ValidatingObject;
//Add the validation errors if available
context.Errors.Add(...);
return Task.CompletedTask;
}
}
ITransientDependency
does it just like in this example)IMethodInvocationValidator
is used to validate a method call. It internally uses the IObjectValidator
to validate objects passes to the method call. You normally don't need to this service since it is automatically used by the framework, but you may want to reuse or replace it on your application in rare cases.
Volo.Abp.FluentValidation package integrates the FluentValidation library to the validation system (by implementing the IObjectValidationContributor
). See the FluentValidation Integration document for more.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4