2013-10-08 30 views
0

我想通過Android上的ksoap將自定義對象發送到我的WCF服務。我有下面的代碼。如何告訴ksoap使用正確的命名空間爲自定義對象添加前綴?

String METHOD_NAME = "MyMethod"; 
String INTERFACE = "IMyInterface"; 
String NAMESPACE = "http://tempuri.org/"; 
String SOAP_ACTION = NAMESPACE + INTERFACE + "/" + METHOD_NAME; 

request = new SoapObject(NAMESPACE, METHOD_NAME); 
request.addProperty("APIKey", API_KEY); 
request.addProperty("AuthToken", AuthToken); 
request.addProperty("UserID", 1); 

SoapObject test1 = new SoapObject(DATA_NAMESPACE, "MyCustomObject"); 
test1.addProperty("ID", 1); 
test1.addProperty("UserID", 1); 
test1.addProperty("Name", "Test"); 
request.addSoapObject(test1); 


SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
envelope.dotNet = true; 
envelope.addMapping(DATA_NAMESPACE, "MyCustomObject", new MyCustomObject().getClass()); 
envelope.setOutputSoapObject(request); 


HttpTransportSE httpTransport = new HttpTransportSE(URL); 
httpTransport.debug = true; 


int id = 0; 
try { 
    httpTransport.call(SOAP_ACTION, envelope); 
    SoapPrimitive result = (SoapPrimitive)envelope.getResponse(); 
    id = Integer.parseInt(result.toString()); 
} catch (Exception e) { 
    String requestDump = httpTransport.requestDump; 
    String responseDump = httpTransport.responseDump; 
    throw e; 
} 

我知道這個調用實際上是將它傳送到網絡服務器。來自APIKey,AuthToken,&用戶標識的值都使其成功。但是,在MyCustomObject中,沒有任何值能夠使它在那裏。該對象確實存在,但它已被剝離了值。

我看了一下requestDump,我發現了以下內容。

<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> 
<MyMethod xmlns="http://tempuri.org/" id="o0" c:root="1"> 
    <APIKey i:type="d:string">MyAPIKey</APIKey> 
    <AuthToken i:type="d:string">MyAuthToken</AuthToken> 
    <UserID i:type="d:int">1</UserID> 
    <MyCustomObject i:type="n0:MyCustomObject" xmlns:n0="http://schemas.datacontract.org/2004/07/MyDataNamespace.Data"> 
    <ID i:type="d:int">1</ID> 
    <UserID i:type="d:int">1</UserID> 
    <Name i:type="d:string">Test</Name> 
    </MyCustomObject> 
</MyMethod> 
</v:Body> 
</v:Envelope> 

然後,我構建了一個快速的.net控制檯客戶端,並執行完全相同的操作。但是,我分析了來自.net客戶端的requestDump並得到了以下結果。

{<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Header> 
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IMyInterface/MyMethod</Action> 
    </s:Header> 
    <s:Body> 
    <MyMethod xmlns="http://tempuri.org/"> 
     <APIKey>MyAPIKey</APIKey> 
     <AuthToken>MyAuthToken</AuthToken> 
     <UserID>1</UserID> 
     <MyCustomObject xmlns:d4p1="http://schemas.datacontract.org/2004/07/MyDataNamespace.Data" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
     <d4p1:Name>Test</d4p1:Name> 
     <d4p1:ID>1</d4p1:ID> 
     <d4p1:UserID>1</d4p1:UserID> 
     </MyCustomObject> 
    </MyMethod> 
    </s:Body> 
</s:Envelope>} 

現在給出的碎片和XML之間的比較,我發現的唯一的事情就是MyCustomObject的屬性與命名空間前綴d4p1前綴。在java客戶端上,屬性不會像n0那樣加上前綴。這會告訴我,這是斷開連接,爲什麼對象正在剝離其屬性。現在的問題是如何告訴ksoap將該名稱空間前綴添加到文檔中?

編輯

而且,這裏是我的類,它實現KVMSerializable。

public class MyCustomObject implements KvmSerializable { 
    public int ID; 
    public int UserID; 
    public String Name; 

    public MyCustomObject() { } 

    public String getName() { return Name; } 
    public int getID() { return ID; } 
    public int getUserID() { return UserID; } 
    public void setName(String name) { Name = name; } 
    public void setID(int ID) { ID = ID; } 
    public void setUserID(int userID) { UserID = userID; } 

    public Object getProperty(int index) { 
     switch (index) { 
      case 0: return ID; 
      case 1: return UserID; 
      case 2: return Name; 
     } 
     return null; 
    } 

    public void setProperty(int index, Object value) { 
     switch (index) { 
      case 0: ID = Integer.parseInt(value.toString()); break; 
      case 1: UserID = Integer.parseInt(value.toString()); break; 
      case 2: Name = value.toString(); break; 
     } 
    } 

    public int getPropertyCount() { return 3; } 

    public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) { 
     switch (index) { 
      case 0: 
       info.type = PropertyInfo.INTEGER_CLASS; 
       info.name = "ID"; 
       break; 
      case 1: 
       info.type = PropertyInfo.INTEGER_CLASS; 
       info.name = "UserID"; 
       break; 
      case 2: 
       info.type = PropertyInfo.STRING_CLASS; 
       info.name = "Name"; 
       break; 
     } 
    } 
} 

編輯1

所以我的第二個問題的問題是屬性的排序。按照建議使用SoapUI向我展示了我的服務器預期的屬性佈局。我需要這樣做,而不是我上面所做的。

test1.addProperty("Name", "Test"); 
test1.addProperty("ID", 1); 
test1.addProperty("UserID", 1); 

回答

1

設置的參數正確的命名空間,即:

PropertyInfo propertyInfo = new PropertyInfo(); 
propertyInfo.setNamespace("http://schemas.datacontract.org/2004/07/MyDataNamespace.Data"); 
propertyInfo.setName("ID"); 
propertyInfo.setValue("1"); 
test1.addProperty(propertyInfo); 
+0

這無疑增加了命名空間的屬性。但是,該對象仍然被剝奪了所有的值。感謝您回答前綴問題。希望我知道它爲什麼要剝離數據。 – meanbunny

+1

Mae的原因是在額外的屬性,如'我:類型'(如果服務器執行驗證)。嘗試刪除它們:[鏈接](http://stackoverflow.com/questions/18299609/android-ksoap2-itype-supression/18318808#18318808)並設置'envelope.setAddAdornments(false);' – esentsov

+0

好吧,所以我沒有嘗試設置'evenlope.setAddAdornments(false);'以及設置'envelope.implicitTypes = true;'以及反之亦然。它似乎不想刪除這些額外的值,所以我將不得不弄清楚如何以某種方式手動刪除它們。 – meanbunny

相關問題