【发布时间】:2015-07-01 18:45:57
【问题描述】:
我在编写用于调用 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 目前是一个空类,供将来使用(我们所有的请求数据合约都使用它):
[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。这可能是缓存问题吗?任何帮助将不胜感激。
【问题讨论】:
-
能否也发布 GenerateFilesRequest 数据合约
-
@jisaak 当然,你去。当我们通过各种其他应用程序调用它时,它非常简单并且工作正常。
-
谢谢。您可以尝试像这样调用 CallFSS:1 .. 100 | % {Write-Host "为 ID $_ 生成文件";调用FSS $_ } 并检查是否还有错误(只是为了确保错误不属于sql查询)
-
仍然得到同样的错误,虽然你刚刚教了我一些很酷的东西:D 1、2、3 工作,4 失败,5 工作,6 失败,7 工作等等。
-
我实现了 GenerateFiles 方法,睡眠时间为 1 秒,然后返回并且什么也不做,并且可以使用 CallFSS 方法调用该方法一百次而不会出现任何错误。也许错误在 GenerateFiles 方法中?您可以尝试清空 GenerateFiles 方法(只需返回)并检查错误是否仍然存在
标签: wcf powershell powershell-3.0 iis-express