Powershell:使用MTOM消息编码消耗WCF服务时出错

时间:2011-04-06 20:53:51

标签: wcf powershell mtom

我目前正在探索powershell功能,但我遇到了一个我无法解决的问题。任何快速提示将非常感激=)

我的目标: 从powershell v2.0调用WCF服务(使用MTOM消息编码配置)中的方法(希望使用new-webserviceproxy cmdlet)

我的问题: 当消息编码设置为Mtom时,new-webserviceproxy cmdlet无法正确解析服务的响应。我收到以下错误:

PowerShell

$proxyObject = New-WebServiceProxy -URI "http://myserver.com/AccessService.svc?wsdl"
$proxyObject.TestWebServiceConnection()

使用“0”参数调用“TestWebServiceConnection”的异常:“客户端发现响应内容类型为'multipart / related; type =”application / xop + xml“; start =”< http://tempuri.org/0> ; “;边界=” UUID:
4001d529-32b9-4560-9f4b-550c35c67b03 + id = 4“; start-info =”text / xml“',但预期'text / xml'。
请求失败并显示错误消息:
-
--uuid:4001d529-32b9-4560-9f4b-550c35c67b03 + ID = 4
Content-ID:< http://tempuri.org/0>
内容传输编码:8位
内容类型:application / xop + xml; charset = utf-8; type =“text / xml”
< s:Envelope xmlns:s =“http://schemas.xmlsoap.org/soap/envelope/”>
< S:车身>
< TestWebServiceConnectionResponse xmlns =“http://myserver.com/”>
< TestWebServiceConnectionResult>成功< / TestWebServiceConnectionResult>
< / TestWebServiceConnectionResponse>
< /秒:车身>
< /秒:信封>
--uuid:4001d529-32b9-4560-9f4b-550c35c67b03 + ID = 4--
- “。
在线:1字符:38
+ $ proxyObject.TestWebServiceConnection<<<< ()>> error.txt
+ CategoryInfo:NotSpecified:(:) [],MethodInvocationException
+ FullyQualifiedErrorId:DotNetMethodException

注意我可以通过其他客户端甚至Microsoft提供的wcfclient工具来使用WCF服务。您可以看到 TestWebServiceConnectionResult 返回成功,但似乎代理对象无法解析响应。

行为

< serviceBehaviors>
< behavior name =“MyServiceBehavior”>
< serviceThrottling maxConcurrentCalls =“100”maxConcurrentSessions =“100”/>
< serviceMetadata httpGetEnabled =“true”httpsGetEnabled =“false”/>
< serviceDebug includeExceptionDetailInFaults =“false”/>
< / behavior>
< / serviceBehaviors>

绑定(我排除了超时值/读者配额和邮件大小,因为它们的值的排列似乎与我的问题无关):


< basicHttpBinding的>
< binding name =“basicHttpEndpointBinding”messageEncoding =“Mtom”>
< security mode =“None”>
< transport clientCredentialType =“None”/>
< / security>
< / basicHttpBinding的>

服务

< service behaviorConfiguration =“MyServiceBehavior”name =“MyService.AccessService”>
< endpoint address =“”binding =“basicHttpBinding”bindingConfiguration =“basicHttpEndpointBinding”name =“basicHttpEndpointAccessService”bindingNamespace =“http://myserver.com/”contract =“MyService.IAccessService”/>
< endpoint address =“mex”binding =“basicHttpBinding”bindingConfiguration =“basicHttpEndpointBinding”name =“mexEndpointAccess”contract =“IMetadataExchange”/>
< /服务>

2 个答案:

答案 0 :(得分:4)

截至撰写本文时,我仍然无法在启用了MTOM的情况下成功使用带有WCF服务的New-WebServiceProxy cmdlet;它看起来不像cmdlet支持它。我的解决方法涉及对wsdl运行svcutil.exe,然后使用csc.exe将类编译为dll。然后我将生成的程序集加载到powershell运行时,然后手动配置端点和代理类的绑定:

从wsdl生成.cs文件:

$svcUri = "http://yourdomain/yourService.svc?wsdl";
$csFile = $className + '.cs';   # The name of the generated .cs file
$dllName = [System.IO.Path]::Combine($temp, $className + ".dll")
$svcUtilresult = svcutil.exe /noConfig /out:$csFile $svcUri

注意 svcutil.execsc.exe可能不在您的powershell的路径中。您可以将其添加到PATH或使用完整路径。您可以在Svcutil中找到Microsoft SDKs\Windows\<version>\bincsc.exe位于%windir%Microsoft .Net文件夹

生成.cs文件后,需要将其编译为dll:

&"csc.exe" /t:library /out:$dllName $csFile

将已编译的dll加载到powershell中:

$fileStream = ([System.IO.FileInfo] (Get-Item ".\$dllName")).OpenRead()
$dllBytes = new-object byte[] $fileStream.Length
$fileStream.Read($dllBytes, 0, $fileStream.Length)
$fileStream.Close()

[System.Reflection.Assembly]::Load($dllBytes)

在powershell中实例化代理客户端:

# Load System.ServiceModel, which can be found in your Framework\v3.0\Windows Communication Foundation folder
[System.Reflection.Assembly]::LoadFile($pathToSystemServiceModel)

# className is the name of your service
$serviceClientName = $className + "Client"

$basicHttpBinding = New-Object System.ServiceModel.BasicHttpBinding
$basicHttpBinding.MessageEncoding = [System.ServiceModel.WSMessageEncoding]::Mtom

$endPoint = New-Object System.ServiceModel.EndpointAddress($svcUri)
$wsClient = New-Object $serviceClientname($basicHttpBinding, $endPoint)

答案 1 :(得分:0)

我遇到了类似的问题。但是我碰巧已经将ClientBase生成的代码编译成本地程序集。

我的解决方案是:

add-type -path "..\..\bin\MYassemblyWithWCFCLient.dll"
$binding = new-object system.servicemodel.basichttpbinding
$binding.MessageEncoding = "Mtom"
$endpoint = new-object System.ServiceModel.EndpointAddress("http://whodunit.oops/mtomandjerry.svc")
$regProxy = new-object MySpecialNamespace.OopsServiceContractClient($binding, $endpoint)