Skip to content

Commit d3392b7

Browse files
committed
Added MiniValidator.RequiresValidation()
Bumped to version 0.6.0
1 parent 73f430d commit d3392b7

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22

33
<PropertyGroup>
4-
<VersionPrefix>0.5.1</VersionPrefix>
4+
<VersionPrefix>0.6.0</VersionPrefix>
55
<VersionSuffix Condition="'$(BuildNumber)' == ''">pre</VersionSuffix>
66
<VersionSuffix Condition="'$(BuildNumber)' != ''">pre.$(BuildNumber)</VersionSuffix>
77
<Authors>Damian Edwards</Authors>

src/MiniValidation/MiniValidator.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Collections.ObjectModel;
45
using System.ComponentModel.DataAnnotations;
56
using System.Linq;
67
using System.Resources;
@@ -15,13 +16,36 @@ namespace MiniValidation
1516
public static class MiniValidator
1617
{
1718
private static readonly TypeDetailsCache _typeDetailsCache = new();
19+
private static readonly IDictionary<string, string[]> _emptyErrors = new ReadOnlyDictionary<string, string[]>(new Dictionary<string, string[]>());
1820

1921
/// <summary>
2022
/// Gets or sets the maximum depth allowed when validating an object with recursion enabled.
2123
/// Defaults to 32.
2224
/// </summary>
2325
public static int MaxDepth { get; set; } = 32;
2426

27+
/// <summary>
28+
/// Determines if the specified <see cref="Type"/> has anything to validate.
29+
/// </summary>
30+
/// <remarks>
31+
/// Objects of types with nothing to validate will always return <c>true</c> when passed to <see cref="TryValidate(object, out IDictionary{string, string[]})"/>.
32+
/// </remarks>
33+
/// <param name="targetType">The <see cref="Type"/>.</param>
34+
/// <param name="recurse"><c>true</c> to recursively check descendant types; if <c>false</c> only simple values directly on the target type are checked.</param>
35+
/// <returns><c>true</c> if the <see cref="Type"/> has anything to validate, <c>false</c> if not.</returns>
36+
/// <exception cref="ArgumentNullException"></exception>
37+
public static bool RequiresValidation(Type targetType, bool recurse = true)
38+
{
39+
if (targetType == null)
40+
{
41+
throw new ArgumentNullException(nameof(targetType));
42+
}
43+
44+
return typeof(IValidatableObject).IsAssignableFrom(targetType)
45+
|| (recurse && typeof(IEnumerable).IsAssignableFrom(targetType))
46+
|| _typeDetailsCache.Get(targetType).Any(p => p.HasValidationAttributes || recurse);
47+
}
48+
2549
/// <summary>
2650
/// Determines whether the specific object is valid. This method recursively validates descendant objects.
2751
/// </summary>
@@ -53,6 +77,14 @@ public static bool TryValidate(object target, bool recurse, out IDictionary<stri
5377
throw new ArgumentNullException(nameof(target));
5478
}
5579

80+
if (!RequiresValidation(target.GetType(), recurse))
81+
{
82+
errors = _emptyErrors;
83+
84+
// Return true for types with nothing to validate
85+
return true;
86+
}
87+
5688
var validatedObjects = new Dictionary<object, bool?>();
5789
var workingErrors = new Dictionary<string, List<string>>();
5890
var isValid = TryValidateImpl(target, recurse, workingErrors, validatedObjects);

0 commit comments

Comments
 (0)