在循环中执行 New-WebServiceProxy 时的不一致行为
Inconsistent behavior when executing New-WebServiceProxy in a loop
我编写的用于调用 WCF Web 服务上的方法的 powershell 脚本有问题。 WCF 服务有一个复合 DataContract 作为其唯一的请求参数。我们最近修改了 ServiceContract(通过添加两个新方法),但是 powershell 脚本没有调用新方法。这是原始合同:
[ServiceContract]
public interface IFileSystemService {
[OperationContract]
HashFileResponse HashFile(HashFileRequest req);
[OperationContract]
void GenerateFiles(GenerateFilesRequest req);
}
这是新合同:
[ServiceContract]
public interface IFileSystemService {
[OperationContract]
HashFileResponse HashFile(HashFileRequest req);
[OperationContract]
void GenerateFiles(GenerateFilesRequest req);
[OperationContract]
ParseFilePathResponse ParseFilePath(ParseFilePathRequest req);
[OperationContract]
ArchiveParsedFileResponse ArchiveParsedFile(ArchiveParsedFileRequest req);
}
GenerateFiles 方法是 PowerShell 脚本调用的方法。我们根本没有修改GenerateFilesRequest DataContract,定义如下:
[DataContract]
public class GenerateFilesRequest : BaseRequest {
[DataMember(IsRequired = true)]
public int Id { get; set; }
}
Baserequest 目前是一个空 class 供将来使用(我们所有的请求数据合约都使用它):
[DataContract]
public abstract class BaseRequest {
}
通过其他方式调用此方法始终有效; SoapUI、Fiddler 和通过在整个应用程序中定义的 WCF 合同。
添加这两个新方法后,我们的集成测试失败了,因为 powershell 脚本无法在循环中一致地调用 GenerateFiles 方法(请参阅错误输出)。
当我最初编写此脚本时,我遇到了类似的问题 运行(尽管它要么一直崩溃,要么一直工作)但我设法通过添加 -Namespace 和-Class New-WebServiceProxy cmdlet 的参数。
上下文:我们是 运行 开发人员计算机上的 powershell 脚本,连接到 IISExpress 中托管的 WCF 服务。所有开发人员都遇到相同的问题。
这是我最近修改之前的原始脚本(首选)(这工作正常,但现在大多数调用都失败了):
$sqlServer=$args[0]
function CallFSS($Id) {
$uri = "http://localhost:1234/FileSystemService.svc?wsdl"
$srv = New-WebServiceProxy -Uri $uri -Namespace fssNS -Class fssClass
$req = [fssNS.GenerateFilesRequest](New-Object fssNS.GenerateFilesRequest)
$req.Id= $Id
$response = $srv.GenerateFiles($req)
}
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=" + $sqlServer + ";Database=MyDatabase;Integrated Security=True"
$SqlConnection.Open()
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = "select Id FROM MyTable WHERE Status = 2"
$SqlCmd.Connection = $SqlConnection
$sqlResult = $SqlCmd.ExecuteReader()
while ($sqlResult.Read()) {
$Id = $sqlResult.GetInt32(0)
Write-Host Generating files for Id $Id
CallFSS $Id
}
$SqlCmd.Dispose()
$SqlConnection.Dispose()
$SqlConnection.Close()
这是脚本输出的摘录。如您所见,这非常不一致(这样标记的行成功):
Generating files for Id 1
Cannot convert argument "req", with value: "fssNS.GenerateFilesRequest", for "GenerateFiles" to type "fssNS.GenerateFilesRequest": "Cannot convert the "fssNS.GenerateFilesRequest" value of type "fssNS.GenerateFilesRequest" to type "fssNS.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Generating files for Id 2
Cannot convert argument "req", with value: "fssNS.GenerateFilesRequest", for "GenerateFiles" to type "fssNS.GenerateFilesRequest": "Cannot convert the "fssNS.GenerateFilesRequest" value of type "fssNS.GenerateFilesRequest" to type "fssNS.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
**Generating files for Id 3**
Generating files for Id 4
Cannot convert argument "req", with value: "fssNS.GenerateFilesRequest", for "GenerateFiles" to type "fssNS.GenerateFilesRequest": "Cannot convert the "fssNS.GenerateFilesRequest" value of type "fssNS.GenerateFilesRequest" to type "fssNS.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument Generating files for Id 8 Cannot convert argument "req", with value: "fssNS.GenerateFilesRequest", for "GenerateFiles" to type "fssNS.GenerateFilesRequest": "Cannot convert the "fssNS.GenerateFilesRequest" value of type "fssNS.GenerateFilesRequest" to type "fssNS.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
**Generating files for Id 9**
**Generating files for Id 10**
**Generating files for Id 11**
Generating files for Id 12
Cannot convert argument "req", with value: "fssNS.GenerateFilesRequest", for "GenerateFiles" to type "fssNS.GenerateFilesRequest": "Cannot convert the "fssNS.GenerateFilesRequest" value of type "fssNS.GenerateFilesRequest" to type "fssNS.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
有时,大多数调用都会通过,只有奇数调用会失败。
这是脚本的另一个版本,它使用 New-WebServiceProxy 自动生成的命名空间:
$sqlServer=$args[0]
function CallFSS($Id) {
$uri = "http://localhost:1234/FileSystemService.svc?wsdl"
$srv = New-WebServiceProxy -Uri $uri
$type = $srv.GetType().Namespace
$datatype = ($type + '.GenerateFilesRequest')
$req = New-Object($datatype)
$req.Id = $Id
$response = $srv.GenerateFiles($req)
}
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=" + $sqlServer + ";Database=MyDatabase;Integrated Security=True"
$SqlConnection.Open()
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = "select Id FROM MyTable WHERE Status = 2"
$SqlCmd.Connection = $SqlConnection
$sqlResult = $SqlCmd.ExecuteReader()
while ($sqlResult.Read()) {
$Id = $sqlResult.GetInt32(0)
Write-Host Generating files for Id $Id
CallFSS $Id
}
$SqlCmd.Dispose()
$SqlConnection.Dispose()
$SqlConnection.Close()
同样,结果不一致,但我现在得到的错误与自动生成的命名空间有关:
**Generating files for Id 1**
**Generating files for Id 2**
Generating files for Id 3
Cannot convert argument "req", with value: "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest", for "GenerateFiles" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest": "Cannot convert the "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest" value of type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Generating files for Id 4
Cannot convert argument "req", with value: "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest", for "GenerateFiles" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest": "Cannot convert the "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest" value of type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
等等...每次执行都不一样
我非常希望这是我做错的事情/误解,因为我即将完全放弃 PowerShell。这可能是缓存问题吗?任何帮助将不胜感激。
好的,我发现了一些东西:)
我在 CallFSS 函数中添加了 GenerateFiles 方法定义的输出:
$srv | gm -Name GenerateFiles | select -ExpandProperty Definition
对于每个成功的请求,输出是
void GenerateFiles(fssNS.GenerateFilesRequest req)
如果遇到错误定义不同:
void GenerateFiles(fssNS.GenerateFilesRequest, oehlvn0y,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null req)
因此,如果您使用完整限定名创建对象,它应该可以工作:
function CallFSS($Id)
{
$uri = "http://localhost:11662/Service1.svc?wsdl"
$srv = New-WebServiceProxy -Uri $uri -Namespace fssNS -Class fssClass
# Get the definition of the GenerateFiles method
$definition = $srv | gm -Name GenerateFiles | select -ExpandProperty Definition
# Extract the full qualified type name of the first parameter
$paramType = [regex]::Match($definition, 'GenerateFiles\((.*)\s\w+').Groups[1].Value
$bar = new-object $paramType
$bar.Id = $Id
$response = $srv.GenerateFiles($bar)
}
注意:由于正则表达式,此解决方案仅适用于具有一个参数的方法。但是,这是我推荐的实现:
function Invoke-FSS # Invoke is a valid Verb (see Get-Verb)
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0)]
[int]$Id
)
Begin
{
$uri = "http://localhost:11662/Service1.svc?wsdl"
$srv = New-WebServiceProxy -Uri $uri -Namespace fssNS -Class fssClass
# Get the definition of the GenerateFiles method
$definition = $srv | gm -Name GenerateFiles | select -ExpandProperty Definition
# Extract the full qualified type name of the first parameter
$paramType = [regex]::Match($definition, 'GenerateFiles\((.*)\s\w+').Groups[1].Value
}
Process
{
$bar = new-object $paramType
$bar.Id = $Id
$response = $srv.GenerateFiles($bar)
}
End
{
$srv.Dispose()
}
}
在您的示例中,您将通过将 ID 传递给 Invoke-FFS
方法来调用该方法:
$ids = @()
while ($sqlResult.Read()) {
$ids += $sqlResult.GetInt32(0)
}
$ids | Invoke-FSS
Begin{}
块仅被调用一次(以初始化您的代理)并且 Process{}
块被调用用于 $ids
中的每个项目。最后,End{}
块在最后被调用一次以优雅地处理代理。
我编写的用于调用 WCF Web 服务上的方法的 powershell 脚本有问题。 WCF 服务有一个复合 DataContract 作为其唯一的请求参数。我们最近修改了 ServiceContract(通过添加两个新方法),但是 powershell 脚本没有调用新方法。这是原始合同:
[ServiceContract]
public interface IFileSystemService {
[OperationContract]
HashFileResponse HashFile(HashFileRequest req);
[OperationContract]
void GenerateFiles(GenerateFilesRequest req);
}
这是新合同:
[ServiceContract]
public interface IFileSystemService {
[OperationContract]
HashFileResponse HashFile(HashFileRequest req);
[OperationContract]
void GenerateFiles(GenerateFilesRequest req);
[OperationContract]
ParseFilePathResponse ParseFilePath(ParseFilePathRequest req);
[OperationContract]
ArchiveParsedFileResponse ArchiveParsedFile(ArchiveParsedFileRequest req);
}
GenerateFiles 方法是 PowerShell 脚本调用的方法。我们根本没有修改GenerateFilesRequest DataContract,定义如下:
[DataContract]
public class GenerateFilesRequest : BaseRequest {
[DataMember(IsRequired = true)]
public int Id { get; set; }
}
Baserequest 目前是一个空 class 供将来使用(我们所有的请求数据合约都使用它):
[DataContract]
public abstract class BaseRequest {
}
通过其他方式调用此方法始终有效; SoapUI、Fiddler 和通过在整个应用程序中定义的 WCF 合同。
添加这两个新方法后,我们的集成测试失败了,因为 powershell 脚本无法在循环中一致地调用 GenerateFiles 方法(请参阅错误输出)。
当我最初编写此脚本时,我遇到了类似的问题 运行(尽管它要么一直崩溃,要么一直工作)但我设法通过添加 -Namespace 和-Class New-WebServiceProxy cmdlet 的参数。
上下文:我们是 运行 开发人员计算机上的 powershell 脚本,连接到 IISExpress 中托管的 WCF 服务。所有开发人员都遇到相同的问题。
这是我最近修改之前的原始脚本(首选)(这工作正常,但现在大多数调用都失败了):
$sqlServer=$args[0]
function CallFSS($Id) {
$uri = "http://localhost:1234/FileSystemService.svc?wsdl"
$srv = New-WebServiceProxy -Uri $uri -Namespace fssNS -Class fssClass
$req = [fssNS.GenerateFilesRequest](New-Object fssNS.GenerateFilesRequest)
$req.Id= $Id
$response = $srv.GenerateFiles($req)
}
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=" + $sqlServer + ";Database=MyDatabase;Integrated Security=True"
$SqlConnection.Open()
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = "select Id FROM MyTable WHERE Status = 2"
$SqlCmd.Connection = $SqlConnection
$sqlResult = $SqlCmd.ExecuteReader()
while ($sqlResult.Read()) {
$Id = $sqlResult.GetInt32(0)
Write-Host Generating files for Id $Id
CallFSS $Id
}
$SqlCmd.Dispose()
$SqlConnection.Dispose()
$SqlConnection.Close()
这是脚本输出的摘录。如您所见,这非常不一致(这样标记的行成功):
Generating files for Id 1
Cannot convert argument "req", with value: "fssNS.GenerateFilesRequest", for "GenerateFiles" to type "fssNS.GenerateFilesRequest": "Cannot convert the "fssNS.GenerateFilesRequest" value of type "fssNS.GenerateFilesRequest" to type "fssNS.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Generating files for Id 2
Cannot convert argument "req", with value: "fssNS.GenerateFilesRequest", for "GenerateFiles" to type "fssNS.GenerateFilesRequest": "Cannot convert the "fssNS.GenerateFilesRequest" value of type "fssNS.GenerateFilesRequest" to type "fssNS.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
**Generating files for Id 3**
Generating files for Id 4
Cannot convert argument "req", with value: "fssNS.GenerateFilesRequest", for "GenerateFiles" to type "fssNS.GenerateFilesRequest": "Cannot convert the "fssNS.GenerateFilesRequest" value of type "fssNS.GenerateFilesRequest" to type "fssNS.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument Generating files for Id 8 Cannot convert argument "req", with value: "fssNS.GenerateFilesRequest", for "GenerateFiles" to type "fssNS.GenerateFilesRequest": "Cannot convert the "fssNS.GenerateFilesRequest" value of type "fssNS.GenerateFilesRequest" to type "fssNS.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
**Generating files for Id 9**
**Generating files for Id 10**
**Generating files for Id 11**
Generating files for Id 12
Cannot convert argument "req", with value: "fssNS.GenerateFilesRequest", for "GenerateFiles" to type "fssNS.GenerateFilesRequest": "Cannot convert the "fssNS.GenerateFilesRequest" value of type "fssNS.GenerateFilesRequest" to type "fssNS.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
有时,大多数调用都会通过,只有奇数调用会失败。
这是脚本的另一个版本,它使用 New-WebServiceProxy 自动生成的命名空间:
$sqlServer=$args[0]
function CallFSS($Id) {
$uri = "http://localhost:1234/FileSystemService.svc?wsdl"
$srv = New-WebServiceProxy -Uri $uri
$type = $srv.GetType().Namespace
$datatype = ($type + '.GenerateFilesRequest')
$req = New-Object($datatype)
$req.Id = $Id
$response = $srv.GenerateFiles($req)
}
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=" + $sqlServer + ";Database=MyDatabase;Integrated Security=True"
$SqlConnection.Open()
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = "select Id FROM MyTable WHERE Status = 2"
$SqlCmd.Connection = $SqlConnection
$sqlResult = $SqlCmd.ExecuteReader()
while ($sqlResult.Read()) {
$Id = $sqlResult.GetInt32(0)
Write-Host Generating files for Id $Id
CallFSS $Id
}
$SqlCmd.Dispose()
$SqlConnection.Dispose()
$SqlConnection.Close()
同样,结果不一致,但我现在得到的错误与自动生成的命名空间有关:
**Generating files for Id 1**
**Generating files for Id 2**
Generating files for Id 3
Cannot convert argument "req", with value: "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest", for "GenerateFiles" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest": "Cannot convert the "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest" value of type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Generating files for Id 4
Cannot convert argument "req", with value: "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest", for "GenerateFiles" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest": "Cannot convert the "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest" value of type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3234_FileSystemService_svc_wsdl.GenerateFilesRequest"." At C:\SolutionPath\GENERATE_FILES.ps1:23 char:2
+ $response = $srv.GenerateFiles($req)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
等等...每次执行都不一样
我非常希望这是我做错的事情/误解,因为我即将完全放弃 PowerShell。这可能是缓存问题吗?任何帮助将不胜感激。
好的,我发现了一些东西:)
我在 CallFSS 函数中添加了 GenerateFiles 方法定义的输出:
$srv | gm -Name GenerateFiles | select -ExpandProperty Definition
对于每个成功的请求,输出是
void GenerateFiles(fssNS.GenerateFilesRequest req)
如果遇到错误定义不同:
void GenerateFiles(fssNS.GenerateFilesRequest, oehlvn0y, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null req)
因此,如果您使用完整限定名创建对象,它应该可以工作:
function CallFSS($Id)
{
$uri = "http://localhost:11662/Service1.svc?wsdl"
$srv = New-WebServiceProxy -Uri $uri -Namespace fssNS -Class fssClass
# Get the definition of the GenerateFiles method
$definition = $srv | gm -Name GenerateFiles | select -ExpandProperty Definition
# Extract the full qualified type name of the first parameter
$paramType = [regex]::Match($definition, 'GenerateFiles\((.*)\s\w+').Groups[1].Value
$bar = new-object $paramType
$bar.Id = $Id
$response = $srv.GenerateFiles($bar)
}
注意:由于正则表达式,此解决方案仅适用于具有一个参数的方法。但是,这是我推荐的实现:
function Invoke-FSS # Invoke is a valid Verb (see Get-Verb)
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0)]
[int]$Id
)
Begin
{
$uri = "http://localhost:11662/Service1.svc?wsdl"
$srv = New-WebServiceProxy -Uri $uri -Namespace fssNS -Class fssClass
# Get the definition of the GenerateFiles method
$definition = $srv | gm -Name GenerateFiles | select -ExpandProperty Definition
# Extract the full qualified type name of the first parameter
$paramType = [regex]::Match($definition, 'GenerateFiles\((.*)\s\w+').Groups[1].Value
}
Process
{
$bar = new-object $paramType
$bar.Id = $Id
$response = $srv.GenerateFiles($bar)
}
End
{
$srv.Dispose()
}
}
在您的示例中,您将通过将 ID 传递给 Invoke-FFS
方法来调用该方法:
$ids = @()
while ($sqlResult.Read()) {
$ids += $sqlResult.GetInt32(0)
}
$ids | Invoke-FSS
Begin{}
块仅被调用一次(以初始化您的代理)并且 Process{}
块被调用用于 $ids
中的每个项目。最后,End{}
块在最后被调用一次以优雅地处理代理。