我正在尝试通过Android上的ksoap将自定义对象发送到我的WCF服务。我在下面有以下代码。
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和&的值UserID都成功完成。但是,在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);
答案 0 :(得分:1)
设置正确的参数命名空间,即:
PropertyInfo propertyInfo = new PropertyInfo();
propertyInfo.setNamespace("http://schemas.datacontract.org/2004/07/MyDataNamespace.Data");
propertyInfo.setName("ID");
propertyInfo.setValue("1");
test1.addProperty(propertyInfo);