validation - 如何为添加的 ScriptMethod 成员强制执行参数?

标签 validation powershell object methods parameters

我有一个 $object,我想有内置函数。我似乎无法弄清楚如何对添加功能的参数强制执行强制规则。

强制规则适用于与对象无关的标准函数,但是当我测试对象并运行函数时,我可以在没有所需强制参数的情况下执行。

 $object | Add-Member -Name ProcessFiles -MemberType ScriptMethod -Value { 
    param(
        [Parameter(Mandatory=$true)]
        [String[]]$FILES
    ) 

这不会引发错误,并且应该提示缺少参数。

$object.ProcessFiles()  

有什么魔力?有人有自定义对象ScriptMethod参数验证的示例代码吗?

最佳答案

这很有趣。我可以确认您所看到的行为(使用 PowerShell 5.0,但我想它始终是相同的)。

我不能确切地说出为什么会发生这种情况,但一定与代码的调用方式有关。

通过做$object.ProcessFiles.Script.Ast.ParamBlock.Parameters.Attributes你可以看到Mandatory参数被保留,只是看起来被忽略了。

解决方法

一个简单的测试

如果您不需要强制参数的所有功能(也就是说,您不关心它是否提示输入值),您可以简单地测试和 throw :

$object | Add-Member -MemberType ScriptMethod -Name test -Value { 
    param(
        [String[]]
        $Files
    )

    if (!$Files) {
        throw [System.ArgumentException]'-Files is required.'
    }
}

更通用的东西

在调查此问题时,我注意到 [ScriptBlock]确实强制执行属性,所以我想出了这个技巧:

$object | Add-Member -MemberType ScriptMethod -Name ProcessFiles -Value { 
    param(
        [String[]]
        $Files
    )

    & {
        param(
            [Parameter(Mandatory=$true)]
            [String[]]
            $Files
        )

        $Files
    } @PSBoundParameters
}

这是在 ScriptMethod 内创建一个接受相同参数的脚本 block ,然后在调用脚本 block 时将所有绑定(bind)参数作为参数传递给脚本 block 。

我还没有使用更复杂的参数声明来测试它,但它应该可以解决问题。

我认为这样做的主要缺点是您需要将 param block 写入两次。如果您在 Add-Member 之外创建脚本 block ,则有一种方法可以避免这种情况。称呼;您可以创建一个将脚本 block 作为参数的函数,然后使用 AST 对其进行解析,并以编程方式创建一个嵌入并执行原始脚本 block 的新脚本 block 。这可能有点过分了;也许我会写一篇关于它的博客文章。

关于validation - 如何为添加的 ScriptMethod 成员强制执行参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33225763/

相关文章:

ruby-on-rails - 事件管理员设计用户 : Update Without Password

validation - ASP.NET MVC 3.0 部分内部和外部具有不显眼的数据验证属性问题的表单

java - Apache Wicket 口 : how to update model after validation error

powershell - 通过多个标签查找azure资源?

python - 如何管理 python turtle 中的事件处理程序递归?

javascript - 使用 lodash 使用一些更新和删除的结果更新数组的最佳方法是什么?

javascript - 使用 Codeigniter 表单验证和 Jquery 序列化

linux - azure 无法从 vhd 镜像创建 vm

c# - 从另一个自定义 cmdlet 运行多个自定义 C# PowerShell cmdlet

java - 使用 Object o = new Object()