11

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

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

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

电源

$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> ";boundary="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>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml; charset=utf-8;type="text/xml"
<s:信封 xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
< TestWebServiceConnectionResponse xmlns="http://myserver.com/">
<TestWebServiceConnectionResult>success</TestWebServiceConnectionResult>
</TestWebServiceConnectionResponse>
</s:Body>
</s:Envelope>
--uuid:4001d529-32b9-4560-9f4b-550c35c67b03+id=4--
--。”
行: 1 char:38
+ $proxyObject.TestWebServiceConnection <<<< () >> error.txt
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

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

行为

<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100"/>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</行为>
</服务行为>

绑定(我已经排除了超时值/阅读器配额和消息大小,因为它们的值的排列似乎与我的问题无关):


<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"/>
</service>
4

2 回答 2

7

在撰写本文时,我仍然无法成功使用New-WebServiceProxycmdlet 和启用了 MTOM 的 WCF 服务;它看起来不像 cmdlet 支持它。我的解决方法是svcutil.exe针对 wsdl 运行,然后使用csc.exe. 然后我将生成的程序集加载到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 中。您可以将其添加到 PATH 或使用完整路径。Svcutil可以在您的Microsoft SDKs\Windows\<version>\bin. csc.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)
于 2012-04-04T22:09:08.560 回答
1

我遇到了类似的问题。但是,我碰巧已经将 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)
于 2013-05-11T00:31:02.223 回答