DamianEdwards / DamianEdwards/MiniValidation

Consider MVC-style configurable child validation suppression

Open
#87 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
C#
Stars
390
Forks
35
PR merge metrics
No merged PRs in 30d

Description

Context

While reviewing PR #83 for #54/#73, we investigated how ASP.NET Core MVC avoids recursion-based validation issues when property getters or framework object graphs are problematic.

MVC generally does not catch exceptions from property getters during validation. Instead, it avoids traversing many risky child graphs through validation metadata:

  • ValidationEntry stores child model access lazily, so MVC can skip entries before invoking a property getter.
  • ValidationVisitor.VisitChildren checks metadata.PropertyValidationFilter?.ShouldValidateEntry(...) before evaluating entry.Model.
  • [ValidateNever] implements IPropertyValidationFilter; MVC has tests proving skipped properties are not accessed.
  • ModelMetadata.ValidateChildren can be set to false by metadata providers.
  • MVC registers default SuppressChildValidationMetadataProviders for framework/terminal types such as Type, Delegate, MethodInfo, MemberInfo, ParameterInfo, Assembly, Uri, CancellationToken, form-file types, and Stream.
  • Newtonsoft MVC setup additionally suppresses child validation for IJsonPatchDocument and JToken.

Relevant ASP.NET Core files observed:

  • src/Mvc/Mvc.Core/src/ModelBinding/Validation/ValidationVisitor.cs
  • src/Mvc/Mvc.Core/src/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs
  • src/Mvc/Mvc.Abstractions/src/ModelBinding/Validation/ValidationEntry.cs
  • src/Mvc/Mvc.Core/src/Infrastructure/MvcCoreMvcOptionsSetup.cs
  • src/Mvc/Mvc.Core/src/ModelBinding/SuppressChildValidationMetadataProvider.cs
  • src/Mvc/Mvc.NewtonsoftJson/src/DependencyInjection/NewtonsoftJsonMvcOptionsSetup.cs

Current MiniValidation behavior

PR #83 addresses the immediate crash reports by treating delegates, reflection types, and selected JSON/dynamic framework namespaces as terminal/non-validatable types. This is directionally similar to MVC's suppression approach and avoids broad getter-exception swallowing.

However, MiniValidation's suppression list is currently hardcoded inside TypeDetailsCache.IsNonValidatableType(...). MiniValidation has [SkipRecursion] for opt-out on model members, but it does not have an MVC-like configurable global mechanism for suppressing recursion into types owned by framework/library packages.

Follow-up idea

Consider adding an options/configuration mechanism for recursive validation suppression, similar in spirit to MVC's SuppressChildValidationMetadataProvider:

  • Allow callers to configure types or predicates that should be treated as terminal for recursion.
  • Seed the default list with MVC-aligned framework types where appropriate.
  • Consider namespace/full-name based suppression for optional dependencies without taking package references, similar to MVC's XML full-type-name provider.
  • Preserve [SkipRecursion] as the per-member opt-out.
  • Avoid broad catch-and-ignore behavior for arbitrary property getter exceptions.

Possible API shapes to explore:

MiniValidator.TryValidate(model, new MiniValidationOptions
{
    SuppressChildValidationTypes = { typeof(Delegate), typeof(Uri) },
    SuppressChildValidationTypeNames = { "Newtonsoft.Json.Linq.JToken" }
}, out var errors);

or static/global defaults if an options object would be too large a change.

Questions

  • Should MiniValidation expose a configurable suppression list, or is a small built-in terminal-type list sufficient?
  • Should MVC's default suppressed types be mirrored exactly, partially, or used only as inspiration?
  • Can this be added without making the public API too option-heavy?
  • Should this be part of a future 0.11.0 feature release or deferred beyond that?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with TypeDetailsCache.IsNonValidatableType(...) and review PR #83, then compare the listed ASP.NET Core MVC files and their suppression behavior. The work is done when the project has an agreed configurable suppression design, including defaults, type-name handling, and compatibility with [SkipRecursion], without broad exception swallowing.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.