dongxian4531 2013-03-07 19:02
浏览 48
已采纳

通过PHP向从C#生成的WSDL发出SOAP请求,挣扎于语法

I've got a web service which was written in C#. I am calling this web service's methods from PHP. All of the methods which expect primitive parameters work great. I'm receiving exceptions when attempting to call a more complex method, though.

Here's my C#:

[WebMethod(Description = "Search components using the specified filters and username.")]
public DataSet Search(AttributeFilter[] filters, string username,
    int[] displayedAttributes, ComponentSearchOptions options,
    bool includeFlags, bool includeIcons)
{
    RemoteComponent remoteComponent = RemoteActivator.Create<RemoteComponent>();

    return remoteComponent.SearchComponents(filters, username, displayedAttributes, options, includeFlags, includeIcons);
}

Here's the associated WSDL:

<s:element name="Search">
    <s:complexType>
        <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="filters" type="tns:ArrayOfAttributeFilter"/>
            <s:element minOccurs="0" maxOccurs="1" name="username" type="s:string"/>
            <s:element minOccurs="0" maxOccurs="1" name="displayedAttributes" type="tns:ArrayOfInt"/>
            <s:element minOccurs="1" maxOccurs="1" name="options" type="tns:ComponentSearchOptions"/>
            <s:element minOccurs="1" maxOccurs="1" name="includeFlags" type="s:boolean"/>
            <s:element minOccurs="1" maxOccurs="1" name="includeIcons" type="s:boolean"/>
        </s:sequence>
    </s:complexType>
</s:element>
<s:complexType name="ArrayOfAttributeFilter">
    <s:sequence>
        <s:element minOccurs="0" maxOccurs="unbounded" name="AttributeFilter" nillable="true" type="tns:AttributeFilter"/>
    </s:sequence>
</s:complexType>
<s:complexType name="AttributeFilter">
    <s:sequence>
        <s:element minOccurs="1" maxOccurs="1" name="Attribute" type="s:int"/>
        <s:element minOccurs="1" maxOccurs="1" name="Comparison" type="tns:SearchComparison"/>
        <s:element minOccurs="0" maxOccurs="1" name="Value"/>
    </s:sequence>
</s:complexType>
<s:simpleType name="SearchComparison">
    <s:restriction base="s:string">
        <s:enumeration value="Equals"/>
        <s:enumeration value="GreaterThan"/>
        <s:enumeration value="GreaterThanOrEqual"/>
        <s:enumeration value="In"/>
        <s:enumeration value="LessThan"/>
        <s:enumeration value="LessThanOrEqual"/>
        <s:enumeration value="Like"/>
    </s:restriction>
</s:simpleType>
<s:simpleType name="ComponentSearchOptions">
    <s:list>
        <s:simpleType>
            <s:restriction base="s:string">
                <s:enumeration value="None"/>
                <s:enumeration value="IncludeCables"/>
                <s:enumeration value="IncludePorts"/>
            </s:restriction>
        </s:simpleType>
    </s:list>
</s:simpleType>
<s:element name="SearchResponse">
    <s:complexType>
        <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="SearchResult">
                <s:complexType>
                    <s:sequence>
                    <s:element ref="s:schema"/>
                    <s:any/>
                    </s:sequence>
                </s:complexType>
            </s:element>
        </s:sequence>
    </s:complexType>
</s:element>

Here is my current attempt in PHP:

$filters = array("filter" => (object)array("AttributeFilter" => (object)array("Attribute" => -2, "SearchComparison" => "Equals", "Value" => "110001")));
$search = $soapClient->Search($filters , "Administrator", NULL, "None", true, true);

and I receive the exception:

SOAP-ERROR: Encoding: object has no 'options' property

Could anyone point me in the right direction? Or let me know if there's something technically impossible about what I am attempting?

Thanks.

Oh, also, here's a C# test case which works:

private readonly ComponentSearchServicesSoapClient ComponentSearchServices = new ComponentSearchServicesSoapClient();

[Test]
public void TestSearchBarcode()
{
    AttributeFilter filter = new AttributeFilter
    {
        Attribute = -2,
        Comparison = SearchComparison.Equals,
        Value = "110001"
    };

    DataSet dataset = ComponentSearchServices.Search(new[] { filter }, "Administrator", null, ComponentSearchOptions.None, false, false);

    if (dataset.Tables.Count == 0 || dataset.Tables[0].Rows.Count != 1)
    {
        throw new Exception("Failed to properly search");
    }
}
  • 写回答

1条回答 默认 最新

  • dongyue0225 2013-03-08 00:23
    关注

    Solution was two-part issue.

    Proper syntax to make the call is:

    $search = $soapClient->Search(array("filters" => array("AttributeFilter" => array('Attribute' => 310, 'Comparison' => 'Equals', 'Value' => 'Peering LAN')), 'username' => 'Administrator', 'displayedAttributes' => array(310), 'options' => 'None', 'includeFlags' => true, 'includeIcons' => true));
    

    Additional issue was that the AttributeFilter class expected the property 'Value' to be of type 'object'. Changing 'Value' to be of type 'string' removed a serialization exception which was occurring.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘