Skip to content

Commit

Permalink
Improvements to rulesets
Browse files Browse the repository at this point in the history
  • Loading branch information
chrissainty committed Jun 1, 2022
1 parent 170ac3d commit d2746f9
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 17 deletions.
1 change: 0 additions & 1 deletion Blazored.FluentValidation.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{D5C6
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8BA5A2FD-3AC9-4D43-A173-E2FA2E0869C7}"
ProjectSection(SolutionItems) = preProject
azure-pipelines.yml = azure-pipelines.yml
README.md = README.md
EndProjectSection
EndProject
Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,26 @@ If you're using async validation, you can use the `ValidateAsync` method on the
}
}
}
```

## RuleSets
[RuleSets](https://docs.fluentvalidation.net/en/latest/rulesets.html) allow validation rules to be grouped and executed together while ignoring other rules. RulesSets are supported in two ways.

The first is setting RuleSets via the `Options` parameter on the `FluentValidationValidator` component.

```razor
<FluentValidationValidator Options="@(options => options.IncludeRuleSets("Names"))" />
```

The second is when manually validating the model using the `Validate` or `ValidateAsync` methods.

```razor
<FluentValidationValidator @ref="_fluentValidationValidator" />
@code {
private FluentValidationValidator? _fluentValidationValidator;
private void PartialValidate()
=> _fluentValidationValidator?.Validate(options => options.IncludeRuleSets("Names"));
}
```
2 changes: 1 addition & 1 deletion samples/BlazorWebAssembly/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<hr class="mb-5" />

<EditForm Model="@_person" OnSubmit="@SubmitFormAsync">
<FluentValidationValidator @ref="_fluentValidationValidator" />
<FluentValidationValidator @ref="_fluentValidationValidator" Options="@(options => options.IncludeAllRuleSets())" />
<ValidationSummary />

<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,22 @@ private static async Task ValidateModel(EditContext editContext,

if (validator is not null)
{
var context = ValidationContext<object>.CreateWithOptions(editContext.Model, fluentValidationValidator.Options ?? (opt => opt.IncludeAllRuleSets()));
ValidationContext<object> context;

if (fluentValidationValidator.ValidateOptions is not null)
{
context = ValidationContext<object>.CreateWithOptions(editContext.Model, fluentValidationValidator.ValidateOptions);
}
else if (fluentValidationValidator.Options is not null)
{
context = ValidationContext<object>.CreateWithOptions(editContext.Model, fluentValidationValidator.Options);
}
else
{
context = new ValidationContext<object>(editContext.Model);
}

var asyncValidationTask = validator.ValidateAsync(context);

editContext.Properties[PendingAsyncValidation] = asyncValidationTask;
var validationResults = await asyncValidationTask;

Expand Down
36 changes: 23 additions & 13 deletions src/Blazored.FluentValidation/FluentValidationsValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,49 +15,59 @@ public class FluentValidationValidator : ComponentBase

[Parameter] public IValidator? Validator { get; set; }
[Parameter] public bool DisableAssemblyScanning { get; set; }
[Parameter] public Action<ValidationStrategy<object>>? Options { get; set; }
internal Action<ValidationStrategy<object>>? ValidateOptions { get; set; }

internal Action<ValidationStrategy<object>>? Options;

public bool Validate(Action<ValidationStrategy<object>> options)
public bool Validate(Action<ValidationStrategy<object>>? options = null)
{
if (CurrentEditContext is null)
{
throw new NullReferenceException(nameof(CurrentEditContext));
}

Options = options;
ValidateOptions = options;

try
{
return CurrentEditContext.Validate();
}
finally
{
Options = null;
ValidateOptions = null;
}
}

/// <summary>
/// Validates this <see cref="EditContext"/>.
/// </summary>
/// <returns>True if there are no validation messages after validation; otherwise false.</returns>
public async Task<bool> ValidateAsync()
public async Task<bool> ValidateAsync(Action<ValidationStrategy<object>>? options = null)
{
if (CurrentEditContext is null)
{
throw new NullReferenceException(nameof(CurrentEditContext));
}

CurrentEditContext.Validate();
ValidateOptions = options;

if (!CurrentEditContext!.Properties.TryGetValue(EditContextFluentValidationExtensions.PendingAsyncValidation, out var asyncValidationTask))
try
{
throw new InvalidOperationException("No pending ValidationResult found");
}
CurrentEditContext.Validate();

await (Task<ValidationResult>)asyncValidationTask;

return !CurrentEditContext.GetValidationMessages().Any();
if (!CurrentEditContext!.Properties.TryGetValue(
EditContextFluentValidationExtensions.PendingAsyncValidation, out var asyncValidationTask))
{
throw new InvalidOperationException("No pending ValidationResult found");
}

await (Task<ValidationResult>) asyncValidationTask;

return !CurrentEditContext.GetValidationMessages().Any();
}
finally
{
ValidateOptions = null;
}
}

protected override void OnInitialized()
Expand Down

0 comments on commit d2746f9

Please sign in to comment.