Unosquare.ModelValidation
1.0.0-alpha.4
dotnet add package Unosquare.ModelValidation --version 1.0.0-alpha.4
NuGet\Install-Package Unosquare.ModelValidation -Version 1.0.0-alpha.4
<PackageReference Include="Unosquare.ModelValidation" Version="1.0.0-alpha.4" />
paket add Unosquare.ModelValidation --version 1.0.0-alpha.4
#r "nuget: Unosquare.ModelValidation, 1.0.0-alpha.4"
// Install Unosquare.ModelValidation as a Cake Addin #addin nuget:?package=Unosquare.ModelValidation&version=1.0.0-alpha.4&prerelease // Install Unosquare.ModelValidation as a Cake Tool #tool nuget:?package=Unosquare.ModelValidation&version=1.0.0-alpha.4&prerelease
A Flexible Model Validation Library
An easy-to-use formatter, validator and postprocessor for user input management.
Motivation
The standard and documented model validation techniques are typically quite inflexible (in my view). If you look at <a href="https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-7.0"> the documentation</a>, you will notice a few things:
- Model validation is mostly based on property attributes
- Adding custom validation requires the implamentation of a
ValidationAttribute
and the scope of the validation logic tends to be limited. For example, validating if a user exists may require a call to a database or an API. While this is possible with theRemoteAttribute
, it introduces unnecessary complexity. - The default validation API does not support strongly-typed access to the model.
- Adding validation to classes for which attributes you cannot modify (i.e. external libraries) does not feel streamlined.
- There is no bult-in functionality to format input and validate it once it has been formatted.
- Validation of only part of the model is not supported. It feels like an all-or-none approach that proves difficult in for example, wizard-oriented scenarios where multi-step data is stored in a single model.
Usage
Please look at the following usage examples below. Notice this API provides a much more flexible approach to validation than the default one. You can define multiple validators for any model class and you can manually change the results as you please.
// Assume the following model class.
public record Employee
{
[Range(1, 10, ErrorMessage = "Unfortunately, this field '{0}' must have a value between {1} and {2}.")]
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string? Email { get; set; }
}
// Create a model validator (there is a non strongly-typed version that you can also use)
var validatior = new ModelValidator<Employee>();
// You can now add the existing validation attributes, either one property at a time:
validator.AddAttributes();
// or one by one (you can use string fro property names if you prefer)
validator.AddAttributes(r => r.Id);
// or add pre-built validation attributes
validator
.AddRequired(r => r.Name)
.AddEmail(r => r.Email);
// or clear existing validation logic and add ValidationAttribute instances without the need
// to modify the class.
validator.Remove(r => r.Id)
validator.AddAttribute(r => r.Id, () => new RangeAttribute(2, 20);
// And last but not least -- add totally custom input formatting and validation
validator.AddCustom(r => r.Id, config =>
{
config
.WithPreValidation((context, value) => 21)
.WithValidation((context, value) =>
{
// you are welcome to make this call async
return value == 21
? context.Pass()
: context.Fail();
})
.WithPostValidation((context, value) => context.SetValue(value));
});
// now you can run your validator as follows:
var target = new Employee();
var validation = await validator.ValidateAsync(target); // there is a synchronous version as well.
// And get either individual results
if (validation.IsInvalid(r => r.Id))
Console.WriteLine(validation.ErrorMessage(r => r.Id));
// or total model validation
if (validation.IsValid)
Console.WriteLine("Your model is valid");
// or manually add errors external to the model validator
validation.Add("SomeField", "This is some manual error message");
// which then would make validation.IsValid, false
if (validation.IsValid)
Console.WriteLine("Your model is valid");
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net7.0
- Microsoft.Extensions.Localization.Abstractions (>= 7.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.0-alpha.4 | 83 | 10/7/2023 |
1.0.0-alpha.3 | 79 | 9/29/2023 |
1.0.0-alpha.2 | 69 | 9/29/2023 |
1.0.0-alpha.1 | 71 | 9/26/2023 |
Please review the examples in the repo for usage.