Powershell: ошибка использования служб WCF с кодировкой сообщений MTOM

в настоящее время я изучаю возможности powershell, но я столкнулся с проблемой, которую я не смог решить. Любые быстрые советы будут очень признательны =)

моя цель: Вызовите методы из службы WCF (настроенной с помощью кодировки сообщений MTOM) из powershell v2.0 (надеюсь, с помощью командлета new-webserviceproxy)

моя проблема: командлет new-webserviceproxy не может правильно проанализировать ответ службы, если для кодировки сообщения задано значение Mtom. Я появляется следующее сообщение об ошибке:

PowerShell:

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

Исключение при вызове "TestWebServiceConnection" с "0" аргумент(ы): "клиент получил ответ типа контента 'multipart/связанный; тип="применение/хор+в XML";начало="&lthttp://tempuri.орг/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: &lthttp: / / tempuri.org / 0 & gt
контент-передача-кодирование: 8 бит
Content-Type: application / xop+xml; charset=utf-8; type= " text / xml"
&lts: конверт xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" & gt
& lts: тело & gt
& ltTestWebServiceConnectionResponse xmlns="http://myserver.com/" & gt
& ltTestWebServiceConnectionResult&gtsuccess&lt/TestWebServiceConnectionResult & gt
& lt/TestWebServiceConnectionResponse & gt
& lt/s: кузов & gt
& lt/s: конверт & gt
--uuid: 4001d529-32b9-4560-9f4b-550c35c67b03+id=4--
--."
на линии: 1 char: 38
+ $proxyObject.TestWebServiceConnection &Л&Л&Л&Л () &ГТ&ГТ ошибка.формат txt
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId: DotNetMethodException

Примечание Я могу использовать службу WCF через других клиентов и даже инструмент wcfclient, предоставляемый Microsoft. Вы можете видеть, что TestWebServiceConnectionResult вернулся успехов, но не похоже, что прокси-объект смог проанализировать ответ.

поведение:

& ltserviceBehaviors & gt
& ltbehavior name= "MyServiceBehavior" & gt
& ltserviceThrottling maxConcurrentCalls= " 100 "maxConcurrentSessions= "100" / & gt
&ltserviceMetadata httpGetEnabled= "true" httpsGetEnabled= "false" / & gt
& ltserviceDebug includeExceptionDetailInFaults="false" / & gt
& lt / поведение & gt
& lt/serviceBehaviors & gt

обязательные(Я исключил значения тайм-аута / квоту чтения и размеры сообщений с тех пор перестановки их значений, похоже, не имеют отношения к моей проблеме):


& ltbasicHttpBinding & gt
& ltbinding name= "basicHttpEndpointBinding" messageEncoding= "Mtom" & gt
& ltsecurity mode= "нет" & gt
& lttransport clientCredentialType= " нет " / & gt
& lt / безопасность & gt
& lt / basicHttpBinding & gt

сервис

& ltservice behaviorConfiguration= "MyServiceBehavior" name= " MyService.AccessService" & gt
& ltendpoint address= ""binding= "basicHttpBinding" bindingConfiguration=" basicHttpEndpointBinding "name=" basicHttpEndpointAccessService " bindingNamespace="http://myserver.com /" контракт= " MyService.IAccessService"/ & gt
& ltendpoint address=" mex "binding= "basicHttpBinding" bindingConfiguration=" basicHttpEndpointBinding "name=" mexEndpointAccess" контракт= "IMetadataExchange" / & gt
& lt / service & gt

2 ответов


на момент написания этой статьи я все еще не смог успешно использовать New-WebServiceProxy командлет со службой WCF с включенным MTOM; не похоже, что командлет поддерживает его. Мое решение вести svcutil.exe против WSDL, а затем компиляции класса в dll с помощью csc.exe. Затем я загрузил созданную сборку во время выполнения powershell, а затем вручную настроил конечную точку и привязку прокси-класса:

генерации .cs файл из ваш 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

Примечание svcutil.exe и csc.exe может не быть в пути powershell. Вы можете либо добавить его в свой путь, либо использовать полный путь. 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)

У меня была аналогичная проблема. Однако у меня уже был сгенерированный код 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)