& { param([AllowNull()] $Foo) $null -eq $Foo } $null
& { param([AllowNull()] [ValidateScript({$true})] $Foo) $null -eq $Foo } $null
& { param([AllowNull()] [ValidateLength(0, 10)] $Foo) $null -eq $Foo } $null
& { param([AllowNull()] [ValidateRange(1,2)] $Foo) $null -eq $Foo } $null
& { param([AllowNull()] [ValidatePattern('.*')] $Foo) $null -eq $Foo } $null
& { param([AllowNull()] [ValidateSet(1,2)] $Foo) $null -eq $Foo } $null
& { param([AllowNull()] [ValidateDrive("c:")] $Foo) $null -eq $Foo } $null
True
True
True
True
True
True
True
To clarify, I expected the following behavior, which I think is a useful combination of AllowNull
and other validation attributes:
If [AllowNull()]
is (also) present:
$null
is actually being passed, allow the value and ignore any other validation attributes.True
param [...] : Cannot validate argument on parameter 'Foo'. The argument is null, empty, or an element of the argument. [...]
[...]
param[...] : Cannot validate argument on parameter 'Foo'. The argument is null, empty, or an element of the argument. [...]
[...]
param[...] : Cannot validate argument on parameter 'Foo'. The argument is null, empty, or an element of the argument. [...]
[...]
param[...] : Cannot validate argument on parameter 'Foo'. The argument is null, empty, or an element of the argument. [...]
[...]
param[...] : Cannot validate argument on parameter 'Foo'. The argument is null, empty, or an element of the argument. [...]
[...]
param[...] : Cannot validate argument on parameter 'Foo'. The argument is null.
The AllowNull
attribute is effectively ignored in the presence of the validation attributes in the snippet; switching the attribute order makes no difference.
Note how the last error message, triggered by the ValidateDrive
attribute, differs.
The following validation attributes _can_ be combined with AllowNull
:
ValidateCount
AllowEmptyString
AllowEmptyCollection
PowerShell Core v6.0.0-beta.3 on macOS 10.12.5
PowerShell Core v6.0.0-beta.3 on Ubuntu 16.04.1 LTS
PowerShell Core v6.0.0-beta.3 on Microsoft Windows 10 Pro (64-bit; v10.0.14393)
Windows PowerShell v5.1.15063.413 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
The attributes are checked one after the other ("and" not "or"). So the Validate attributes would also allow null, but it's not. I believe the behavior is by design.
@iSazonov:
Passing $null
to param([AllowNull()] [ValidateScript({$true})] $Foo)
satisfies _both_ attributes, for instance, yet it fails as described.
By contrast, passing $null
to param([AllowNull()] [ValidateCount(0,1)] $Foo)
works.
To me it makes sense to allow these combinations, assuming the AllowNull
attribute is explicitly specified.
Please clarify that we meant:
& { param( [ValidateScript({$true})] $Foo) $null -eq $Foo } $null
param([ValidateScript({$true})] $Foo) $null -eq $Foo : Cannot validate argument on parameter 'Foo'. The argument is null, empty, or an element of the ...
@iSazonov:
I'm not sure I understand.
Yes, you can get the same symptom by omitting the [AllowNull()]
attribute.
In other words: using an attribute such as [ValidateScript()]
implicitly disallows $null
, which would otherwise be allowed by default (in the absence of [Parameter(Mandatory)]
).
Again, the point is that I think it makes sense to allow this combination, if [AllowNull()]
is explicitly specified.
@mklement0 Thanks for clarify! There is another side - we should have the same behavior for PowerShell scripts and C# codes.
@iSazonov:
Re C#: Do you mean when writing compiled cmdlets? Are there existing differences?
Sorry, no difference.
Do you want the behavior: if [AllowNull()]
attribute is passed then stop processing next attributes?
Yes, but only if $null
is being passed; in other words:
If [AllowNull()]
is (also) present:
$null
is actually being passed, allow the value and ignore any other validation attributes.Thanks for clarify! Please move the explanation in first post.
@iSazonov: Done.
Most helpful comment
Yes, but only if
$null
is being passed; in other words:If
[AllowNull()]
is (also) present:$null
is actually being passed, allow the value and ignore any other validation attributes.