Ksoap2 Android - 如何为复杂对象的子属性指定命名空间?

时间:2012-03-06 16:16:03

标签: android wcf web-services ksoap2

我正在尝试使用KSoap2 Android将复杂对象上传到WCF Web服务,并且在执行此操作时遇到一些困难。当我使用SoapUI并手动填写数据时,我已成功调用webservice。成功的SoapUI生成的请求如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:fpm="http://schemas.datacontract.org/2004/07/FPMobileServices">
<soapenv:Header/>
<soapenv:Body>
  <tem:CommitOne>
     <tem:qr>
        <fpm:ClientID>8aa2f6a4-4d15-4b4c-9cac-fb2478d0d27a</fpm:ClientID>
        <fpm:CreatedBy>admin</fpm:CreatedBy>
        <fpm:CreatedDate>2012-03-01T19:50:37</fpm:CreatedDate>
        <fpm:DimensionID>8a02a339-b5a7-4c76-b95f-5891ef57736d</fpm:DimensionID>
        <fpm:ImageID>b76c7bcc-a8f8-49ff-94c6-08cd2e05b1a8</fpm:ImageID>
        <fpm:IndicatorID>4637b333-701d-4d03-a708-4de48569be84</fpm:IndicatorID>
        <fpm:LoanOperationNumber>6-2011-72978</fpm:LoanOperationNumber>
        <fpm:ModifiedBy>admin</fpm:ModifiedBy>
        <fpm:ModifiedDate>2012-03-01T19:50:37</fpm:ModifiedDate>
        <fpm:QuestionaireCompletedDate>2012-03-01T19:50:54</fpm:QuestionaireCompletedDate>
        <fpm:QuestionnaireID>99967f70-8161-4922-929f-03136a389ba6</fpm:QuestionnaireID>
        <fpm:ResultID>95fa03b5-80af-479d-9dec-f2bf94baf3cd</fpm:ResultID>
        <fpm:ResultWeighting>0</fpm:ResultWeighting>
        <fpm:StatusLevelID>03a91cd6-93cd-4503-a676-efa2967e82a7</fpm:StatusLevelID>
        <fpm:UploadID>141D6A1F-8FFD-4CA4-8073-009338F22B13</fpm:UploadID>
     </tem:qr>
  </tem:CommitOne>
</soapenv:Body>
</soapenv:Envelope>

我的Java代码生成的请求是:

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
    <CommitOne xmlns="http://tempuri.org/" id="o0" c:root="1">
        <qr>
            <ClientID>8aa2f6a4-4d15-4b4c-9cac-fb2478d0d27a</ClientID>
            <LoanOperationNumber>6-2011-72978</LoanOperationNumber>
            <CreatedBy i:null="true" />
            <CreatedDate>2012-03-01T19:50:37</CreatedDate>
            <DimensionID>8a02a339-b5a7-4c76-b95f-5891ef57736d</DimensionID>
            <ImageID>b76c7bcc-a8f8-49ff-94c6-08cd2e05b1a8</ImageID>
            <IndicatorID>4637b333-701d-4d03-a708-4de48569be84</IndicatorID>
            <ModifiedBy i:null="true" />
            <ModifiedDate i:null="true" />
            <QuestionnaireCompletedDate>2012-03-01T19:50:54</QuestionnaireCompletedDate>
            <QuestionnaireID>99967f70-8161-4922-929f-03136a389ba6</QuestionnaireID>
            <ResultID i:type="d:string">95fa03b5-80af-479d-9dec-f2bf94baf3cc</ResultID>
            <ResultWeighting>0</ResultWeighting>
            <StatusLevelID>03a91cd6-93cd-4503-a676-efa2967e82a7</StatusLevelID>
            <UploadID i:type="d:string">8ffa3665-b691-486f-91a0-ebbe8575896c</UploadID>
        </qr>
    </CommitOne>
</v:Body>

两者之间的主要区别似乎是前缀/名称空间。出于某种原因,当“qr”对象到达我的.NET代码时,其所有属性都为null / zero。

我在我的java代码中尝试了两种不同的方法,试图将我的“qr”对象设置为PropertyInfo:

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 

    // build request object 
    PropertyInfo qrPi = new PropertyInfo();
    qrPi.setName("qr");
    qrPi.setType(qr.getClass());
    qrPi.setValue(qr);

    request.addProperty(qrPi); 

还将我的“qr”设置为SoapObject,然后使用.addProperty:

    SoapObject result = new SoapObject(NAMESPACE, "qr");
    result.addProperty("ClientID", (String) qr.getClientID());
    result.addProperty("CreatedBy", (String) qr.getCreatedBy());
    result.addProperty("CreatedDate", (String) qr.getCreatedDate());
    result.addProperty("DimensionID", (String) qr.getDimensionID());
    result.addProperty("ImageID", (String) qr.getImageID());
    result.addProperty("IndicatorID", (String) qr.getIndicatorID());
    result.addProperty("LoanOperationNumber", (String) qr.getLoanOperationNumber());
    result.addProperty("ModifiedBy", (String) qr.getModifiedBy());
    result.addProperty("ModifiedDate", (String) qr.getModifiedDate());
    result.addProperty("QuestionnaireCompletedDate", (String) qr.getQuestionnaireCompletedDate());
    result.addProperty("QuestionnaireID", (String) qr.getQuestionnaireID());
    result.addProperty("ResultID", (String) qr.getResultID());
    result.addProperty("ResultWeighting", qr.getResultWeighting());
    result.addProperty("StatusLevelID", (String) qr.getStatusLevelID());
    result.addProperty("UploadID", (String) qr.getUploadID());

    request.addSoapObject(result); 

但是这两种方法都得到了相同的结果 - 当我的“qr”对象的字段进入我的webservice时,它们都是null。我一直在寻找StackOverflow上的类似问题并找到this,但我无法弄清楚如何将它应用到我自己的案例中。

任何人都可以帮助了解情况吗?

2 个答案:

答案 0 :(得分:11)

不确定我是否应该回答我自己的问题,但我已经找到了一个解决方案,并将其留给任何有类似问题的人。

关键是不同的命名空间。在SoapUI生成的示例中,我们可以看到子元素(ClientID等)使用fpm命名空间,而它们上面的元素使用tem命名空间。为了明确指定这些子元素的命名空间,我改变了上面讨论的第二种方法 - 我为每个子元素创建了PropertyInfo对象,并将它们添加到SoapObject中。

而不是使用:

result.addProperty(String "ClientID", Object qr.getClientID());

我用过:

PropertyInfo pi = new PropertyInfo();
pi.setNamespace(QR_NAMESPACE);
pi.setType(PropertyInfo.STRING_CLASS);
pi.setName("ClientID");
pi.setValue(qr.getClientID()); 
result.addProperty(pi);

当我使用所有属性执行此操作时,它工作正常。

希望有一天能帮助别人!

答案 1 :(得分:0)

我遇到了类似的问题,但是我的对象实现了KvmSerializable并且KSoap自动序列化它们(它们是由wsdl2code从WSDL生成的)。在这种情况下,最简单的解决方案是在父PropertyInfo.namespace方法中设置getPropertyInfo,如下所示:

@Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
    switch(index){
        case 0:
            info.type = Person.class;
            info.name = "Person";
            info.namespace = "http://schemas.example.com/crm";
            break;
    }
}