0

我正在尝试通过 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;
}

我知道该调用实际上是发送到 Web 服务器的。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);
4

1 回答 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);
于 2013-10-08T11:57:10.657 回答