Add ErrorMessage property to ValidatePattern, ValidateSet and ValidateScript attributes (#2728)
This makes it possibe to write for example [ValidatePattern('[A-Z]:', ErrorMessage='The Drive should be specified as a single letter followed by a colon, for example "D:"')] [string] $Drive, The element being validated is also passed, so {0} can be used in the custom error message
This commit is contained in:
parent
e8a0f3ca63
commit
fa901b646f
|
@ -1113,6 +1113,17 @@ namespace System.Management.Automation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RegexOptions Options { set; get; } = RegexOptions.IgnoreCase;
|
public RegexOptions Options { set; get; } = RegexOptions.IgnoreCase;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the custom error message pattern that is displayed to the user.
|
||||||
|
///
|
||||||
|
/// The text representation of the object being validated and the validating regex is passed as
|
||||||
|
/// the first and second formatting parameters to the ErrorMessage formatting pattern.
|
||||||
|
/// <example>
|
||||||
|
/// [ValidatePattern("\s+", ErrorMessage="The text '{0}' did not pass validation of regex '{1}'")]
|
||||||
|
/// </example>
|
||||||
|
/// </summary>
|
||||||
|
public string ErrorMessage { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validates that each parameter argument matches the RegexPattern
|
/// Validates that each parameter argument matches the RegexPattern
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1136,8 +1147,9 @@ namespace System.Management.Automation
|
||||||
Match match = regex.Match(objectString);
|
Match match = regex.Match(objectString);
|
||||||
if (!match.Success)
|
if (!match.Success)
|
||||||
{
|
{
|
||||||
|
var errorMessageFormat = String.IsNullOrEmpty(ErrorMessage) ? Metadata.ValidatePatternFailure : ErrorMessage;
|
||||||
throw new ValidationMetadataException("ValidatePatternFailure",
|
throw new ValidationMetadataException("ValidatePatternFailure",
|
||||||
null, Metadata.ValidatePatternFailure,
|
null, errorMessageFormat,
|
||||||
objectString, RegexPattern);
|
objectString, RegexPattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1163,6 +1175,18 @@ namespace System.Management.Automation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class ValidateScriptAttribute : ValidateEnumeratedArgumentsAttribute
|
public sealed class ValidateScriptAttribute : ValidateEnumeratedArgumentsAttribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the custom error message that is displayed to the user.
|
||||||
|
///
|
||||||
|
/// The item being validated and the validating scriptblock is passed as the first and second
|
||||||
|
/// formatting argument.
|
||||||
|
///
|
||||||
|
/// <example>
|
||||||
|
/// [ValidateScript("$_ % 2", ErrorMessage = "The item '{0}' did not pass validation of script '{1}'")]
|
||||||
|
/// </example>
|
||||||
|
/// </summary>
|
||||||
|
public string ErrorMessage { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the scriptblock to be used in the validation
|
/// Gets the scriptblock to be used in the validation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1193,8 +1217,9 @@ namespace System.Management.Automation
|
||||||
|
|
||||||
if (!LanguagePrimitives.IsTrue(result))
|
if (!LanguagePrimitives.IsTrue(result))
|
||||||
{
|
{
|
||||||
|
var errorMessageFormat = String.IsNullOrEmpty(ErrorMessage) ? Metadata.ValidateScriptFailure : ErrorMessage;
|
||||||
throw new ValidationMetadataException("ValidateScriptFailure",
|
throw new ValidationMetadataException("ValidateScriptFailure",
|
||||||
null, Metadata.ValidateScriptFailure,
|
null, errorMessageFormat,
|
||||||
element, ScriptBlock);
|
element, ScriptBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1336,6 +1361,18 @@ namespace System.Management.Automation
|
||||||
{
|
{
|
||||||
private string[] _validValues;
|
private string[] _validValues;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the custom error message that is displayed to the user
|
||||||
|
///
|
||||||
|
/// The item being validated and a text representation of the validation set
|
||||||
|
/// is passed as the first and second formatting argument to the ErrorMessage formatting pattern.
|
||||||
|
///
|
||||||
|
/// <example>
|
||||||
|
/// [ValidateSet("A","B","C", ErrorMessage="The item '{0}' is not part of the set '{1}'.")
|
||||||
|
/// </example>
|
||||||
|
/// </summary>
|
||||||
|
public string ErrorMessage { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a flag specifying if we should ignore the case when performing string comparison. The
|
/// Gets a flag specifying if we should ignore the case when performing string comparison. The
|
||||||
/// default is true.
|
/// default is true.
|
||||||
|
@ -1386,8 +1423,10 @@ namespace System.Management.Automation
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errorMessageFormat = String.IsNullOrEmpty(ErrorMessage) ? Metadata.ValidateSetFailure : ErrorMessage;
|
||||||
throw new ValidationMetadataException("ValidateSetFailure", null,
|
throw new ValidationMetadataException("ValidateSetFailure", null,
|
||||||
Metadata.ValidateSetFailure,
|
errorMessageFormat,
|
||||||
element.ToString(), SetAsString());
|
element.ToString(), SetAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1313,6 +1313,10 @@ namespace System.Management.Automation.Language
|
||||||
{
|
{
|
||||||
result.IgnoreCase = s_attrArgToBoolConverter.Target(s_attrArgToBoolConverter, argValue);
|
result.IgnoreCase = s_attrArgToBoolConverter.Target(s_attrArgToBoolConverter, argValue);
|
||||||
}
|
}
|
||||||
|
else if (argumentName.Equals("ErrorMessage", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
result.ErrorMessage = argValue.ToString();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw InterpreterError.NewInterpreterException(namedArg, typeof(RuntimeException), namedArg.Extent,
|
throw InterpreterError.NewInterpreterException(namedArg, typeof(RuntimeException), namedArg.Extent,
|
||||||
|
|
|
@ -412,6 +412,62 @@
|
||||||
|
|
||||||
{ get-fooh } | Should not throw
|
{ get-fooh } | Should not throw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
It "ValidateScript can use custom ErrorMessage" {
|
||||||
|
function get-fooi {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param([ValidateScript({$_ -gt 2}, ErrorMessage = "Item '{0}' failed '{1}' validation")] $p)
|
||||||
|
$p
|
||||||
|
}
|
||||||
|
$errMsg = ''
|
||||||
|
try
|
||||||
|
{
|
||||||
|
get-fooi -p 2
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
$errMsg = $_.Exception.Message
|
||||||
|
}
|
||||||
|
$errMsg | Should Be "Cannot validate argument on parameter 'p'. Item '2' failed '`$_ -gt 2' validation"
|
||||||
|
}
|
||||||
|
|
||||||
|
It "ValidatePattern can use custom ErrorMessage" {
|
||||||
|
function get-fooj
|
||||||
|
{
|
||||||
|
[CmdletBinding()]
|
||||||
|
param([ValidatePattern("\s+", ErrorMessage = "Item '{0}' failed '{1}' regex")] $p)
|
||||||
|
$p
|
||||||
|
}
|
||||||
|
$errMsg = ''
|
||||||
|
try
|
||||||
|
{
|
||||||
|
get-fooj -p 2
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
$errMsg = $_.Exception.Message
|
||||||
|
}
|
||||||
|
$errMsg | Should Be "Cannot validate argument on parameter 'p'. Item '2' failed '\s+' regex"
|
||||||
|
}
|
||||||
|
|
||||||
|
It "ValidateSet can use custom ErrorMessage" {
|
||||||
|
function get-fook
|
||||||
|
{
|
||||||
|
param([ValidateSet('A', 'B', 'C', IgnoreCase=$false, ErrorMessage="Item '{0}' is not in '{1}'")] $p)
|
||||||
|
}
|
||||||
|
$errMsg = ''
|
||||||
|
try
|
||||||
|
{
|
||||||
|
get-fook -p 2
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
$errMsg = $_.Exception.Message
|
||||||
|
}
|
||||||
|
$set = 'A','B','C' -join [Globalization.CultureInfo]::CurrentUICulture.TextInfo.ListSeparator
|
||||||
|
$errMsg | Should Be "Cannot validate argument on parameter 'p'. Item '2' is not in '$set'"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#known issue 2069
|
#known issue 2069
|
||||||
|
|
Loading…
Reference in a new issue