我有一个运行在服务器上的 .NET WCF Web 服务,我可以从几台不同的计算机访问该服务。为了测试我的连接性,我有一个 PowerShell 脚本,它构建代理、连接到 Web 服务、发送消息并断开连接。构建代理的代码来自这里:http ://www.ilovesharepoint.com/2008/12/call-wcf-services-with-powershell.html
我有一个批处理文件,它运行脚本的多次迭代(500 次),我看到不同的行为取决于我在哪台客户端计算机上运行测试脚本:
- COMPUTER A:成功运行脚本,没有任何失败。完成所有 500 次迭代大约需要 15 分钟。
- 计算机 B:迭代失败的概率约为 3% - 4%。完成所有 500 次迭代需要1 个多小时。故障每 3-5 分钟发生一次。
当脚本失败时,我收到的消息是:
使用“0”参数调用“GetMetadata”的异常:“元数据包含无法解析的引用:'https://SERVER:8733/WSEngineService/?WSDL'。” 在 D:\CLIENT\proxyTest.ps1:32 char:41 + $metadataSet = $mexClient.GetMetadata <<<< () + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : DotNetMethodException
异常的堆栈跟踪是:
在 System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformation methodInformation, Object[] originalArguments) 在 System.Management.Automation.DotNetAdapter.MethodInvokeDotNet(String methodName, Object target, MethodInformation [] methodInformation,对象 [] 参数)在 System.Management.Automation.Adapter.BaseMethodInvoke(PSMethod 方法,对象 [] 参数)在 System.Management.Automation.ParserOps.CallMethod(令牌令牌,对象目标,字符串方法名,对象 [] 参数阵列, Boolean callStatic, Object valueToSet) at System.Management.Automation.MethodCallNode.InvokeMethod(Object target, Object[] arguments, Object value) at System.Management.Automation.MethodCallNode.Execute(Array input, Pipe outputPipe,ExecutionContext 上下文)在 System.Management.Automation.AssignmentStatementNode.Execute(数组输入,管道 outputPipe,ExecutionContext 上下文)在 System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode 语句,数组输入,管道输出管道,ArrayList 和结果列表,ExecutionContext 上下文)
MEX 客户端属性为:
PS D:\CLIENT>>> $mexClient
SoapCredentials : System.ServiceModel.Description.ClientCredentials
HttpCredentials :
OperationTimeout : 00:01:00
MaximumResolvedReferences : 2147483647
ResolveMetadataReferences : True
这是发生异常的代码:
# get metadata of a service
function global:Get-WsdlImporter($wsdlUrl=$(throw "parameter -wsdlUrl is missing"), $httpGet)
{
if($httpGet -eq $true)
{
$local:mode = [System.ServiceModel.Description.MetadataExchangeClientMode]::HttpGet
}
else
{
$local:mode = [System.ServiceModel.Description.MetadataExchangeClientMode]::MetadataExchange
}
$mexClient = New-Object System.ServiceModel.Description.MetadataExchangeClient((New-Object System.Uri($wsdlUrl)),$mode)
$mexClient.MaximumResolvedReferences = [System.Int32]::MaxValue
$metadataSet = $mexClient.GetMetadata() # <-- Fails sometimes on COMPUTER B but never on COMPUTER A.
$wsdlImporter = New-Object System.ServiceModel.Description.WsdlImporter($metadataSet)
return $wsdlImporter
}
我的网络服务配置如下:
<behavior name="WsTuBehaviorConfig">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" httpsGetBinding="" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="40" maxConcurrentSessions="40" maxConcurrentInstances="40" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom" membershipProviderName="Ldap" customUserNamePasswordValidatorType="MyProduct.Framework.Security.AuthenticationProvider.UserNamePasswordLdapUserId,MyProduct.Framework.Security.AuthenticationProvider" />
</serviceCredentials>
<serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="LdapOperationProvider" />
<useRequestHeadersForMetadataAddress />
</behavior>
<ws2007HttpBinding>
<binding name="ws2007HttpTuBindingConfig" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="3200" maxStringContentLength="8192" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Basic" proxyCredentialType="None" />
<message clientCredentialType="None" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</ws2007HttpBinding>
<service behaviorConfiguration="WsTuBehaviorConfig" name="MyProduct.BusinessLibrary.Services.WSEngineService">
<endpoint name="WsEngineWs2007HttpEp" address="ws2007HttpEP" binding="ws2007HttpBinding" bindingConfiguration="ws2007HttpTuBindingConfig" behaviorConfiguration="accessDeniedFaultBehaviorConfig" contract="MyProduct.BusinessLibrary.Services.IWSEngineService" />
<endpoint name="mexWSEngineEP" address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://SERVER:8733/WSEngineService/" />
</baseAddresses>
</host>
</service>
我告诉代理测试脚本忽略任何 SSL 警告:
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
我不知道为什么脚本偶尔会在计算机 B 上失败,但在计算机 A 上从未失败。不幸的是,计算机 B 是一个负载驱动程序,用于针对 Web 服务运行性能测试,并且这些故障阻碍了我的能力进行测试。我不能使用 COMPUTER A 进行测试,因为我不想进入这里。我可以看到两台计算机之间的唯一区别是计算机 A 是 Windows 7 Professional 工作站,计算机 B 是 Windows 2008 R2 服务器。两者都安装了相同版本的 .NET 框架和 PowerShell。
有人对为什么 COMPUTER B 无法尝试获取我的 Web 服务的元数据有任何想法吗?