我一直在尝试通过Powershell使用供应商提供的Web服务系统(我正在运行4.0)。 以下是我用于设置代理以使用该服务的代码:
$uri = http://somehost.employer.net:9999/AdministrationService?wsdl
$webSvc = New-WebServiceProxy -Uri $uri -namespace WebServiceProxy -Credential $TestCreds_NonPriv
目前,我对该服务公开的两种方法感兴趣," SaveAttributes"和" GetAllAttributes", wsdl定义如下:
<xsd:element name="SaveAttributes">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="Id" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="attributes" nillable="true" type="q5:ArrayOfKeyValueOfstringstring"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="GetAllAttributes">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="Id" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="GetAllAttributesResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="GetAllAttributesResult" nillable="true" type="q2:ArrayOfKeyValueOfstringstring"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
我通过以下方式成功使用了GetAllAttributes函数:
$websvc.GetAllAttributes('someid')
这会返回一个对象,它是一个键值对数组,如下所示:
Key Value
--- -----
ID 01
PERSONA godeater@stackoverflow.com
NAME GodEater's real name
如果我想在Web服务上创建一个新对象,我必须调用&#34; SaveAttributes&#34;功能 两个参数,一个新的&#34; ID&#34;作为字符串和其余属性的键/值对数组, 这就是我难倒的地方。我无法创建成功序列化的powershell对象 服务。我试过的是:
[WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring[]]$newentity = @(
@{Key='PERSONA';Value='someone_else@stackoverflow.com'},
@{Key='NAME';Value='Someone Elses Real Name'}
)
$WebSvc.SaveAttributes('02',$newentity)
但我得到的是这个相当令人困惑的错误:
Cannot convert argument "attributes", with value: "WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring[]", for "SaveAttributes" to type
"WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring[]": "Cannot convert the "WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring" value of type
"WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring" to type "WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring"."
At line:1 char:1
+ $WebSvc.SaveAttributes('02',$newentity)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
现在,看看GetAllAttributes返回给我的是什么,它应该和我一样对象 尝试提供“属性”#39; SaveAttributes方法的参数,似乎稍微序列化 与我自己构建的对象不同。
序列化时来自GetAllAttributes的结果:
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring[]</T>
<T>System.Array</T>
<T>System.Object</T>
</TN>
<LST>
<Obj RefId="1">
<TN RefId="1">
<T>WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring</T>
<T>System.Object</T>
</TN>
<ToString>WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring</ToString>
<Props>
<S N="Key">ID</S>
<S N="Value">01</S>
</Props>
</Obj>
<Obj RefId="2">
<TNRef RefId="1" />
<ToString>WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring</ToString>
<Props>
<S N="Key">PERSONA</S>
<S N="Value">godeater@stackoverflow.com</S>
</Props>
</Obj>
<Obj RefId="3">
<TNRef RefId="1" />
<ToString>WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring</ToString>
<Props>
<S N="Key">NAME</S>
<S N="Value">GodEater's real name</S>
</Props>
</Obj>
</LST>
</Obj>
</Objs>
虽然我创建的对象序列化为:
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>System.Collections.Hashtable</T>
<T>System.Object</T>
</TN>
<DCT>
<En>
<S N="Key">PERSONA</S>
<S N="Value"></S>
</En>
</DCT>
</Obj>
</Objs>
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>System.Collections.Hashtable</T>
<T>System.Object</T>
</TN>
<DCT>
<En>
<S N="Key">NAME</S>
<S N="Value">Someone Elses Real Name</S>
</En>
</DCT>
</Obj>
</Objs>
这似乎缺乏围绕数组成员的包装,而似乎相反 将数组中的每个项目作为独立对象。
有人有什么想法吗?
答案 0 :(得分:2)
在Powershell中将复杂的自定义类型传递给Web服务方法似乎是一个常见问题。 在这里,他们建议将'-Class'参数添加到New-WebServiceProxy: https://groups.google.com/forum/#!msg/microsoft.public.windows.powershell/JWB5yueLtrg/k0zeUUxAkTMJ
在我的情况下它没有帮助 - 似乎这个解决方案也不稳定。 我最后不得不使用自动生成的命名空间来避免这个问题。
应该创建没有名称空间的Web服务代理:
$webSvc = New-WebServiceProxy -Uri $uri
然后在自动生成的命名空间中创建数组:
$newentity = New-Object -TypeName ($webSvc.GetType().Namespace + '.ArrayOfKeyValueOfstringstringKeyValueOfstringstring[]') -ArgumentList 2
$newentity[0] = New-Object -TypeName ($webSvc.GetType().Namespace + '.ArrayOfKeyValueOfstringstringKeyValueOfstringstring')
$newentity[0].Key = 'key0'
$newentity[0].Value = 'value0'
$newentity[1] = New-Object -TypeName ($webSvc.GetType().Namespace + '.ArrayOfKeyValueOfstringstringKeyValueOfstringstring')
$newentity[1].Key = 'key1'
$newentity[1].Value = 'value1'
$WebSvc.SaveAttributes('02',$newentity)
看起来很笨拙,但至少它对我有用。
答案 1 :(得分:1)
尝试强制键/值对为WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring
类型:
$Properties = @(
@{Key='PERSONA';Value='someone_else@stackoverflow.com'},
@{Key='NAME';Value='Someone Elses Real Name'}
)
[WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring[]]$newentity = $Properties | ForEach-Object {
New-Object -TypeName 'WebServiceProxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring' -Property $_
}
$WebSvc.SaveAttributes('02',$newentity)