Powershell Salesforce SOAP API SessionHeader类型Converion问题

时间:2014-07-30 18:00:40

标签: api powershell soap salesforce

您好我在设置SessionHeaderValue时遇到问题。我的代码基于c#.Net。登录工作正常,我在登录结果中收到serviceUrl和sessionId,但我无法在会话标题中设置会话ID

这是代码

$uri = "c:\installs\sforce.wsdl"
$username = "username"
$password = "password"
# Proxy
$service = New-WebServiceProxy -Uri $uri -Namespace sforce -UseDefaultCredential
# Login
$loginResult = $service.login($username, $password)
$service.Url = $loginResult.serverUrl
$service.SessionHeaderValue = New-Object sforce.SessionHeader

这是我得到的错误,有点奇怪。

异常设置" SessionHeaderValue":"无法转换" sforce.SessionHeader" type" sforce.SessionHeader"输入" sforce.SessionHeader"。"

我已经玩了几个小时了,现在已经没想完了。

感谢任何帮助。

安东尼

4 个答案:

答案 0 :(得分:0)

我发现webpage意味着应该使用以下内容创建$service.SessionHeaderValue实例:

$service.SessionHeaderValue = New-ObjectFromProxy -proxy $service -proxyAttributeName "SessionHeaderValue" -typeName "SessionHeader"

PowerShell + SOAP + AuthenticationInfoValue中有一个New-ObjectFromProxy函数的定义:

function New-ObjectFromProxy {
    param($proxy, $proxyAttributeName, $typeName)

    # Locate the assembly for $proxy
    $attribute = $proxy | gm | where { $_.Name -eq $proxyAttributeName }
    $str = "`$assembly = [" + $attribute.TypeName + "].assembly"
    invoke-expression $str

    # Instantiate an AuthenticationHeaderValue object.
    $type = $assembly.getTypes() | where { $_.Name -eq $typeName }

    return $assembly.CreateInstance($type)
}

我并不自称是PowerShell专家,但看起来New-Object创建的对象实例与代理对象所期望的类型并不相同。令人困惑的是,它们确实有相同的名称。

答案 1 :(得分:0)

真正的问题是您无法重复$service。您的$service实例仅对登录有用,而且就是这样。我认为这是由于New-WebServiceProxy的工作方式。检查这个小脚本:

$uri = 'file://C:\projects\CRM\SalesForce\Integration\enterprise.xml'
$api = new-webserviceproxy -uri $uri -NameSpace SalesForce

$api.GetType().Module.Assembly.ManifestModule.ScopeName

$api = new-object SalesForce.SforceService.ScopeName
$api.GetType().Module.Assembly.ManifestModule

如果您要运行此脚本,(当然您需要替换自己的WSDL),您会看到类似的内容(DLL是动态的,因此名称会有所不同):

mhgl0l5w.dll 
vzecopaq.dll

请注意,不仅$ api的对象引用不同,而且New-WebServiceProxy为每个引用创建的动态程序集也不同,这不是您所期望的。这就是你演员失败的原因;具有相同名称的对象是不同的,因为它们来自不同的动态程序集。我不确定为什么行为是这样的 - 如果它是New-WebServiceProxy的特性,或者是SalesForce的WSDL中的某种特性。

解决方案实际上非常简单。从New-WebServiceProxy生成的命名空间重新创建服务对象,如下所示:

$uri = "c:\installs\sforce.wsdl"
$username = "username"
$password = "password"
# Proxy
$service = New-WebServiceProxy -Uri $uri -Namespace sforce -UseDefaultCredential

# Login
$loginResult = $service.login($username, $password)

$service = New-Object sforce.SforceService
$service.Url = $loginResult.serverUrl
$service.SessionHeaderValue = New-Object sforce.SessionHeader

答案 2 :(得分:0)

还值得注意的是,您不能为同一名称空间两次定义Web服务代理。这是流所必需的,您需要转到SOAP API进行登录,然后将会话ID传递给元数据API进行请求。

比较:

    $LoginResponse = $sf.login($username, $password)
    $newSession = $LoginResponse.sessionId
    $newURL = $LoginResponse.serverUrl
    $service = New-Object sforce.SforceService
    $service.Url = $LoginResponse.serverUrl
    $service.SessionHeaderValue = New-Object sforce.SessionHeader
    $service.SessionHeaderValue.sessionId = $LoginResponse.sessionId

    # Set the batch size to 2000
    # Though, if it contains two long text area fields, it will set it as 200
    # This is to avoid long SOAP messages and is controlled by SF
    $service.QueryOptionsValue = new-Object sforce.QueryOptions
    $service.QueryOptionsValue.batchSize = 2000
    $service.QueryOptionsValue.batchSizeSpecified = $true


    $mdservice= new-WebServiceProxy -URI $mdwsdl -Namespace sforce
    $mdservice = New-Object sforce.MetadataService
    $mdservice.Url = $LoginResponse.metadataServerUrl
    $mdservice.SessionHeaderValue = New-Object sforce.SessionHeader
    $mdservice.SessionHeaderValue.sessionId = $LoginResponse.sessionId

这将产生以下错误:

"sforce.SessionHeader" to type "sforce.SessionHeader"."
At line:22 char:5
+     $mdservice.SessionHeaderValue = New-Object sforce.SessionHeader
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

The property 'sessionId' cannot be found on this object. Verify that the property exists and can be set.
At line:23 char:5
+     $mdservice.SessionHeaderValue.sessionId = $LoginResponse.sessionI ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound

以下代码不会出错:

    $sf = new-WebServiceProxy -URI $pwsdl -Namespace sforce
    $LoginResponse = $sf.login($username, $password)
    $newSession = $LoginResponse.sessionId
    $newURL = $LoginResponse.serverUrl
    $service = New-Object sforce.SforceService
    $service.Url = $LoginResponse.serverUrl
    $service.SessionHeaderValue = New-Object sforce.SessionHeader
    $service.SessionHeaderValue.sessionId = $LoginResponse.sessionId

    # Set the batch size to 2000
    # Though, if it contains two long text area fields, it will set it as 200
    # This is to avoid long SOAP messages and is controlled by SF
    $service.QueryOptionsValue = new-Object sforce.QueryOptions
    $service.QueryOptionsValue.batchSize = 2000
    $service.QueryOptionsValue.batchSizeSpecified = $true


    $mdservice= new-WebServiceProxy -URI $mdwsdl #Don't set namespace here
    # Notice that we are getting the namespace dynamically
    $type = $mdservice.GetType().NameSpace
    $mdservice = New-Object ($type + '.MetadataService')
    $mdservice.Url = $LoginResponse.metadataServerUrl
    $mdservice.SessionHeaderValue = New-Object ($type + '.SessionHeader')
    $mdservice.SessionHeaderValue.sessionId = $LoginResponse.sessionId

答案 3 :(得分:-1)

异常设置“SessionHeaderValue”:“无法将类型为”sforce.SessionHeader“的”sforce.SessionHeader“值转换为”sforce.SessionHeader“。”

$service.SessionHeaderValue = New-Object sforce.SessionHeader

在New-Object之后,您必须指定正确的类名。试试这个:

#Login to Salesforce
$loginResults = $service.login($username,$password)

#set the session Id in partner Object 
$service.Url = $loginResults.serverUrl
$sessionHeaderObjClassName = ($service.GetType().FullName) -replace "SforceService","SessionHeader"
$service.SessionHeaderValue = New-Object $sessionHeaderObjClassName
$service.SessionHeaderValue.sessionId = $loginResults.sessionId