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

发布于 2024-10-31 03:55:55 字数 2753 浏览 0 评论 0 原文

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

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

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

PowerShell

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

使用“0”参数调用“TestWebServiceConnection”时出现异常:“客户端发现响应内容类型为‘multipart/lated; type="application/xop+xml";start="4001d529-32b9-4560-9f4b-550c35c67b03+id=4";start-info="text/xml"',但预期为“text/xml”。
请求失败并显示错误消息:
--
--uuid:4001d529-32b9-4560-9f4b-550c35c67b03+id=4
内容 ID:
内容传输编码:8位
内容类型:application/xop+xml;charset=utf-8;type="text/xml"



成功



--uuid:4001d529-32b9-4560-9f4b-550c35c67b03+id=4--
--”。
行:1 字符:38
+ $proxyObject.TestWebServiceConnection <<<<< ()>>错误.txt
+ CategoryInfo : 未指定: (:) [], MethodInitationException
+FullyQualifiedErrorId:DotNetMethodException

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

行为

<服务行为>
<行为名称=“MyServiceBehavior”>




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


<基本HttpBinding>
<绑定名称=“basicHttpEndpointBinding”messageEncoding=“Mtom”>
<安全模式=“无”>
<传输 clientCredentialType="None"/>

服务

<服务行为配置=“MyServiceBehavior”名称=“MyService.AccessService”>
<端点地址=“”绑定=“basicHttpBinding”绑定配置=“basicHttpEndpointBinding”名称=“basicHttpEndpointAccessService”绑定名称空间=“http://myserver.com/”合同=“MyService.IAccessService”/>
<端点地址=“mex”绑定=“basicHttpBinding”绑定配置=“basicHttpEndpointBinding”名称=“mexEndpointAccess”契约=“IMetadataExchange”/>

I'm currently exploring powershell capabilities, but I have encountered a problem that I have not been able to solve. Any quick tips would be greatly appreciated =)

My goal:
Invoke methods from a WCF service (configured with MTOM message encoding) from powershell v2.0 (hopefully using the new-webserviceproxy cmdlet)

My problem:
the new-webserviceproxy cmdlet cannot parse the service's response correctly when message encoding is set to Mtom. I receive the following error:

PowerShell:


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

Exception calling "TestWebServiceConnection" with "0" argument(s): "Client found response content type of 'multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="uuid:

4001d529-32b9-4560-9f4b-550c35c67b03+id=4";start-info="text/xml"', but expected 'text/xml'.

The request failed with the error message:

--

--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:Envelope 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--

--."

At line:1 char:38

+ $proxyObject.TestWebServiceConnection <<<< () >> error.txt

+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException

+ FullyQualifiedErrorId : DotNetMethodException

Note I am able to consume the WCF service through other clients and even the wcfclient tool provided by Microsoft. You can see that the TestWebServiceConnectionResult returned success, but it doesn't seem like the proxy object was able to parse the response.

Behavior:

<serviceBehaviors>

<behavior name="MyServiceBehavior">

<serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100"/>

<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>

<serviceDebug includeExceptionDetailInFaults="false"/>

</behavior>

</serviceBehaviors>

Binding(I've excluded the timeout values/ reader quota and message sizes since the permutations of their values do seem not relevant to my problem):

<basicHttpBinding>

<binding name="basicHttpEndpointBinding" messageEncoding="Mtom">

<security mode="None">

<transport clientCredentialType="None"/>

</security>

</basicHttpBinding>

Service

<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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七色彩虹 2024-11-07 03:55:55

截至撰写本文时,我仍然无法在启用了 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 中。您可以将其添加到 PATH 中或使用完整路径。 Svcutil 可以在 Microsoft SDKs\Windows\\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)

As of the time of this writing, I still have not been able to successfully use the New-WebServiceProxy cmdlet with a WCF service with MTOM enabled; it does not look like the cmdlet supports it. My workaround involved running svcutil.exe against the wsdl, and then compiling the class into a dll using csc.exe. I then loaded the generated assembly into the powershell run time, and then configured the endpoint and binding of the proxy class manually:

Generating the .cs file from your wsdl:

$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

Note svcutil.exe and csc.exe may not be in your powershell's PATH. You can either add it to your PATH or use the full path. Svcutil can be found within your Microsoft SDKs\Windows\<version>\bin. csc.exe is located in your %windir%Microsoft .Net folder

Once you have generated the .cs file, you will need to compile it into a dll:

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

Load the compiled dll into 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)

Instantiate the proxy client in 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)
变身佩奇 2024-11-07 03:55:55

我也有类似的问题。但是我碰巧已经将 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)

I was having a similar problem. However I happened to already have the ClientBase generated code compiled into a local assembly.

My solution was:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文