【问题标题】:New-WebServiceProxy fails with InvalidOperationExceptionNew-WebServiceProxy 失败并出现 InvalidOperationException
【发布时间】:2019-08-30 01:51:44
【问题描述】:

我正在尝试将工作中的 SOAP 客户端(用 Perl 编写)移植到 PowerShell 以用于不同的客户端(他们不允许我们用 Perl 污染他们锁定的 Windows 环境)。

所以我尝试下载 WSDL 信息以创建代理,使用我在 Web 上找到的示例。这就是现有 Perl 代码的工作方式,因此该方法是合理的。

$soap = New-WebServiceProxy -Uri $url -UseDefaultCredential

New-WebServiceProxy : The HTML document does not contain Web service discovery information.
At line:1 char:9
+ $soap = New-WebServiceProxy -Uri $uri
    +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (http://localhos...sx:Uri) [New-WebServiceProxy], InvalidOperationException
    + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.NewWebServiceProxy

但是,正如我所说,这是基于工作代码的,因此服务器端不太可能出现任何问题。作为测试,输入

$WebResponse = Invoke-WebRequest -UseDefaultCredential $url

$WebResponse

我得到:

StatusCode        : 200
StatusDescription : OK
Content           : `<?xml version="1.0" encoding="UTF-8"?>

                    <!-- SOAP API definitions -->
                    <definitions name="SOAPAPI"

这是我所期望的 - 它是 WSDL 标头的开始。

我没有看到发生了什么问题,有人有什么建议吗?

【问题讨论】:

  • 暗中刺伤:将?wsdl 添加到$uri 的值有帮助吗?
  • 在这种情况下,没有。我们知道 uri 是正确的 - 它是由现有 Perl 代码生成的,我们将 WSDL 作为 Invoke-WebRequest 中的内容返回。
  • 你的变量是 $uri 还是 $url?该错误与您的代码不同
  • 你看过这篇文章吗? stackoverflow.com/questions/27793078/…
  • 抱歉,这里有一个错字。变量是 $url,在我的 PS 历史中是一致的。

标签: powershell soap wsdl


【解决方案1】:

简短的回答 - 放弃。它不起作用。作为一种解决方法,使用 Invoke-WebRequest -OutFile(这很重要)下载 WSDL 并使用本地文件 Uri 调用 New-Webserviceproxy。如果需要身份验证,请根据需要手动设置 Credentials 或 UseDefaultCredentials 属性(将参数设置为 New-Webserviceproxy 没有任何效果)。它现在可以工作了,但我不得不得出结论,除了 MS 服务之外,底层的 .Net c# 代码从未经过任何测试......

无论如何,这就是解决方案:


        <#
    -----------------------------------------------------------------
        Phase 1: Download the service description (WSDL)

        We ought to be able to simply invoke the New-WebProxyService cmdlet with
        the URI of the service description, but that consistently fails, possibly because
        this is not a .Net application.

        So the workaround is to download the service description to a temporary file, and
        load that in New-WebServiceProxy as a file::/// URI
    -----------------------------------------------------------------
    #>

        $tmp = New-TemporaryFile
        $tmpName = $tmp.FullName

        # Splatting all the parameters to the cmdlet is more readable than a mix of command line
        # and splatted parameters 
        $wsdlArgs = @{
            Uri = -join ($uri,'?trid=', $service)
            OutFile = $tmpName
            PassThru = $true
            ErrorAction = 'Stop'
        }
        if ($Credential -eq [System.Management.Automation.PSCredential]::Empty) {
            $wsdlArgs['UseDefaultCredentials'] = $true
        }
        else {
            $wsdlArgs['Credential'] = $Credential
        }
        $wsdlResponse = Invoke-WebRequest @wsdlArgs # No try/catch here - if it fails, we fail!

    <#
    -----------------------------------------------------------------
        Phase 2: Create a WebServiceProxy Object

        We use try {} / finally {} to ensure that whether our cmdlet succeeds or fails,
        we clean up our mess...
    -----------------------------------------------------------------
    #>

        # Splatting all the parameters to the cmdlet is more readable than a mix of command line
        # and splatted parameters 
        $soapArgs = @{
            Uri         = ([System.Uri]($tmpName)).AbsoluteUri
            Class       = 'SOAPAPI'
            Namespace   = "www.kambe.com.au"
            ErrorAction = 'Stop'
        }
        try {
            $soap = New-WebServiceProxy @soapArgs # No catch block, if the cmdlet fails, we fail!
        }
        finally { # Whether the cmdlet succeeds or fails, we remove the temp file
            Remove-Item $tmpName -Force
        }

        # It seems the Credential and UseDefaultCredential params are ignored by New-WebServiceProxy if not used?
        # Programming pragmatism: it works this way, and not any other way
        if ($Credential -eq [System.Management.Automation.PSCredential]::Empty) {
            $soap.UseDefaultCredentials = $true
        }
        else {
            $soap.Credentials = $Credential
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 2017-11-01
    • 2014-05-21
    相关资源
    最近更新 更多