2012-10-11 33 views
4

我想用ksoap2來訪問Android的wcf soap服務中的方法。 我能夠成功地將簡單的類型參數傳遞給方法,它工作正常。 但是,當我嘗試傳遞對象時,wcf方法正在接收所有對象值爲0的值。從android使用kso​​ap2傳遞對象到wcf soap服務;它發送和接收0

我已經使用了WP7應用程序相同的SOAP服務,並運行良好。

我有我的服務,ksoapadd和addParam 2種方法。 addParam需要兩個整數並返回它們的總和(這是有效的)。 ksoapadd接受具有兩個整數元素的類testadd的對象,並且ksoapadd返回它們的總和(這得到併發送0)。

我認爲這是與命名空間,但我無法弄清楚如何解決它。我一直在做試驗和錯誤以獲得肥皂請求,但沒有運氣。

任何人都可以幫我弄清楚該怎麼辦?我嘗試了很多方法,以某種方式幫助其他有類似問題的人,但無濟於事。

這裏是我的WSDL:

<?xml version="1.0" encoding="UTF-8"?> 
-<wsdl:definitions xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" 
xmlns:wsa10="http://www.w3.org/2005/08/addressing" 
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" 
xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" 
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
xmlns:tns="http://tempuri.org/" 
xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
targetNamespace="http://tempuri.org/" name="Service1"> 
-<wsdl:types> 
-<xsd:schema targetNamespace="http://tempuri.org/Imports"> 
<xsd:import namespace="http://tempuri.org/" schemaLocation="http://localhost:51086/Service1.svc?xsd=xsd0"/> 
<xsd:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" schemaLocation="http://localhost:51086/Service1.svc?xsd=xsd1"/> 
<xsd:import namespace="http://schemas.datacontract.org/2004/07/InsertIntoUserWCF" schemaLocation="http://localhost:51086/Service1.svc?xsd=xsd2"/> 
</xsd:schema> 
</wsdl:types> 
-<wsdl:message name="IService1_ksoapAdd_InputMessage"> 
<wsdl:part name="parameters" element="tns:ksoapAdd"/> 
</wsdl:message> 
-<wsdl:message name="IService1_ksoapAdd_OutputMessage"> 
<wsdl:part name="parameters" element="tns:ksoapAddResponse"/> 
</wsdl:message> 
-<wsdl:message name="IService1_addParam_InputMessage"> 
<wsdl:part name="parameters" element="tns:addParam"/> 
</wsdl:message> 
-<wsdl:message name="IService1_addParam_OutputMessage"> 
<wsdl:part name="parameters" element="tns:addParamResponse"/> 
</wsdl:message> 
-<wsdl:portType name="IService1"> 
-<wsdl:operation name="ksoapAdd"> 
<wsdl:input message="tns:IService1_ksoapAdd_InputMessage" wsaw:Action="http://tempuri.org/IService1/ksoapAdd"/> 
<wsdl:output message="tns:IService1_ksoapAdd_OutputMessage" wsaw:Action="http://tempuri.org/IService1/ksoapAddResponse"/> 
</wsdl:operation> 
-<wsdl:operation name="addParam"> 
<wsdl:input message="tns:IService1_addParam_InputMessage" wsaw:Action="http://tempuri.org/IService1/addParam"/> 
<wsdl:output message="tns:IService1_addParam_OutputMessage" wsaw:Action="http://tempuri.org/IService1/addParamResponse"/> 
</wsdl:operation> 
</wsdl:portType> 
-<wsdl:binding name="BasicHttpBinding_IService1" type="tns:IService1"> 
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> 
-<wsdl:operation name="InsertUserDetails"> 
<soap:operation style="document" 
-<wsdl:operation name="ksoapAdd"> 
<soap:operation style="document" soapAction="http://tempuri.org/IService1/ksoapAdd"/> 
-<wsdl:input> 
<soap:body use="literal"/> 
</wsdl:input> 
-<wsdl:output> 
<soap:body use="literal"/> 
</wsdl:output> 
</wsdl:operation> 
-<wsdl:operation name="addParam"> 
<soap:operation style="document" soapAction="http://tempuri.org/IService1/addParam"/> 
-<wsdl:input> 
<soap:body use="literal"/> 
</wsdl:input> 
-<wsdl:output> 
<soap:body use="literal"/> 
</wsdl:output> 
</wsdl:operation> 
</wsdl:binding> 
-<wsdl:service name="Service1"> 
-<wsdl:port name="BasicHttpBinding_IService1" binding="tns:BasicHttpBinding_IService1"> 
<soap:address location="http://localhost:51086/Service1.svc"/> 
</wsdl:port> 
</wsdl:service> 
</wsdl:definitions> 

這是我xsd2:

<?xml version="1.0" encoding="UTF-8"?> 
-<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/InsertIntoUserWCF" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://schemas.datacontract.org/2004/07/InsertIntoUserWCF" 
elementFormDefault="qualified"> 
-<xs:complexType name="testadd"> 
-<xs:sequence> 
<xs:element name="number_1" type="xs:int" minOccurs="0"/> 
<xs:element name="number_2" type="xs:int" minOccurs="0"/> 
</xs:sequence> 
</xs:complexType> 
<xs:element name="testadd" type="tns:testadd" nillable="true"/> 
</xs:schema> 

這裏是我的SOAP請求:

<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> 
<ksoapAdd xmlns="http://tempuri.org/" id="o0" c:root="1"> 
<n0:num1 xmlns:n0="http://tempuri.org/"> 
<number_1>25</number_1> 
<number_2>25</number_2> 
</n0:num1> 
</ksoapAdd> 
</v:Body> 
</v:Envelope> 

SOAP響應:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
<s:Body> 
<ksoapAddResponse xmlns="http://tempuri.org/"> 
<ksoapAddResult>0</ksoapAddResult> 
</ksoapAddResponse> 
</s:Body> 
</s:Envelope> 

這是使用kso​​ap2我的Java代碼:

private static final String NAMESPACE = "http://tempuri.org/"; 
private static final String URL = "http://10.0.2.2:51086/Service1.svc?wsdl"; 
private static final String SOAP_ACTION4 = "http://tempuri.org/IService1/ksoapAdd"; 
private static final String METHOD_NAME4 = "ksoapAdd"; 
private static final String SOAP_ACTION5 = "http://tempuri.org/IService1/addParam"; 
private static final String METHOD_NAME5 = "addParam"; 

try { 
    testadd numX = new testadd(25,25); 

    SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME4); 

    PropertyInfo prop = new PropertyInfo(); 
    prop.setNamespace(NAMESPACE); 
    prop.setName("num1"); 
    prop.setType(numX.getClass()); 
    prop.setValue(numX); 
    Request.addProperty(prop); 

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
    envelope.dotNet = true; 
    envelope.setOutputSoapObject(Request); 

    envelope.implicitTypes = true; 

    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); 
    androidHttpTransport.debug=true; 
    androidHttpTransport.call(SOAP_ACTION4, envelope); 

    Log.d(logtag + " request dump", androidHttpTransport.requestDump); 
    Log.d(logtag + " response dump", androidHttpTransport.responseDump); 

    final SoapPrimitive response = (SoapPrimitive)envelope.getResponse(); 
    final int num = Integer.parseInt(response.toString()); 

    } catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 

這是我的java類testadd:

import java.util.Hashtable; 
import org.ksoap2.serialization.KvmSerializable; 
import org.ksoap2.serialization.PropertyInfo; 

public class testadd implements KvmSerializable{ 
int number1; 
int number2; 

testadd(){} 
testadd(int a, int b){ number1 = a; number2 = b;} 


@Override 
public Object getProperty(int arg0) { 
    switch(arg0) 
    { 
    case 0: 
     return number1; 
    case 1: 
     return number2; 

    } 

return null; 
} 

@Override 
public int getPropertyCount() { 

    return 2; 
} 

@Override 
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) { 

    switch(arg0) 
     { 
     case 0: 
      arg2.type = PropertyInfo.INTEGER_CLASS; 
      arg2.name = "number_1"; 
      break; 
     case 1: 
      arg2.type = PropertyInfo.INTEGER_CLASS; 
      arg2.name = "number_2"; 
      break; 

     default:break; 
     } 

} 

@Override 
public void setProperty(int arg0, Object value) { 

    switch(arg0) 
    { 
    case 0: 
     number1 = Integer.parseInt(value.toString()); 
     break; 
    case 1: 
     number2 = Integer.parseInt(value.toString()); 
     break; 

    default: 
     break; 
    } 
} 
} 

服務代碼:

<ServiceContract()> _ 
Public Interface IService1 
<OperationContract()> _ 
Function ksoapAdd(ByVal num1 As testadd) As Integer 

<OperationContract()> _ 
Function addParam(ByVal num1 As Integer, ByVal num2 As Integer) As Integer 

End Interface 

<DataContract()> _ 
Public Class testadd 
Private number1 As Integer 
Private number2 As Integer 

<DataMember()> _ 
Public Property number_1() As Integer 
    Get 
     Return number1 
    End Get 
    Set(ByVal value As Integer) 
     number1 = value 
    End Set 
End Property 

<DataMember()> _ 
Public Property number_2() As Integer 
    Get 
     Return number2 
    End Get 
    Set(ByVal value As Integer) 
     number2 = value 
    End Set 
End Property 

End Class 

服務方法:

Public Function ksoapAdd(ByVal num1 As testadd) As Integer Implements IService1.ksoapAdd 
    MsgBox(num1.number_1) 
    Return num1.number_1 + num1.number_2 
End Function 

Public Function addParam(ByVal num1 As Integer, ByVal num2 As Integer) As Integer Implements IService1.addParam 
    MsgBox(num1 + num2) 
    Return num1 + num2 
End Function 

我知道這是很多代碼,但它認爲有必要了解整個圖片。

謝謝!

+0

只是代碼量和良好的格式,你應得到upvote ...但我今天用完了...這是我最後一個... – Yaroslav

+0

謝謝,我希望有人給我一些輸入不久。 –

回答

5

我終於搞定了!

原來我的Android ksoap2代碼不喜歡通過WCF在SOAP服務設置默認的命名空間(tempuri.org)。

我的猜測是,與默認命名空間,請求信封無法映射傳遞testadd對象,其中testadd類是在服務中定義的datacontract。通過在WCF服務中明確定義一個名稱空間給servicecontract和datacontract,這將改變/重新排列wsdl並使數據合同可訪問。

我跟着本教程擺脫了tempuri。組織namespace- http://blogs.msdn.com/b/endpoint/archive/2011/05/12/how-to-eliminate-tempuri-org-from-your-service-wsdl.aspx

我加在服務代碼的相應位置以下(VB)

<ServiceContract(Namespace:="http://wcfservicetest.org/Service1")> _ 
<DataContract(Namespace:="http://wcfservicetest.org/Service1")> _ 
<ServiceBehavior(Namespace:="http://wcfservicetest.org/Service1")> _ 

我改變了我的命名空間 「http://wcfservicetest.org/Service1」 和編輯NAMESPACE以及具有新命名空間的android java代碼中的SOAP_ACTION。

這樣做後,我得到了我想要的結果!

下面是SOAP請求:

<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> 
<ksoapAdd xmlns="http://wcfservicetest.org/Service1" id="o0" c:root="1"> 
<n0:num1 xmlns:n0="http://wcfservicetest.org/Service1"> 
<number_1>25</number_1> 
<number_2>25</number_2> 
</n0:num1> 
</ksoapAdd> 
</v:Body> 
</v:Envelope> 

SOAP響應:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
<s:Body> 
<ksoapAddResponse xmlns="http://wcfservicetest.org/Service1"> 
<ksoapAddResult>50</ksoapAddResult> 
</ksoapAddResponse> 
</s:Body> 
</s:Envelope> 

所以我的建議給其他人的學習與ksoap2 SOAP服務,做到不使用默認的命名空間,設置自己的命名空間。我花了一個星期試圖弄清楚這一點。

希望這有助於某個人!

+0

OMG你完全救了我,我被困了一個多星期!謝謝 :) – user1746708

相關問題