复杂对象托管.NET Web服务的复杂对象数组

时间:2011-06-13 17:45:37

标签: android ksoap2 android-ksoap2

我在使用来自Android设备的KSOAP2发送到.NET Web服务的复杂对象的属性上收到“强制转换”错误。该属性是一个复杂对象的数组。互联网上的文档帮助我发送和接收简单的数据类型(字符串,整数,日期等)。我甚至可以从.NET Web服务中读取一系列复杂对象。我只是无法将一系列复杂对象发送回Web服务。请帮忙。这就是我所拥有的:

环境: Client = Android Development使用最新的KSOAP lib进行通信。 Server = .NET Web服务(Visual Studio 2008)。注意:这不是WCF。

.NET Web服务:

[SoapRpcMethod(), WebMethod]    
public void WriteCaseInfo(CaseInformation caseInfo)
{
    ...
    ...
}


ANDROID客户端代码:

作为复杂参数发送的父类:

public class CaseInformation extends IABaseKSoap2Serializable
{
public String Name;
public int Id;  
public Vector<MultiPartDataElement> SiteListItems = new Vector<MultiPartDataElement>();

@Override
public Object getProperty(int arg0) 
{
    switch(arg0)
    {
    case 0:
        return Name;
    case 1:
        return Id;
    case 2:
        return SiteListItems;           
    }

    return null;
}

@Override
public int getPropertyCount() 
{
    return 3;
}

@Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) 
{
    switch(index)
    {
    case 0:
        info.type = PropertyInfo.STRING_CLASS;
        info.name = "Name";
        break;
    case 1:
        info.type = PropertyInfo.INTEGER_CLASS;
        info.name = "Id";
        break;
    case 2:
        info.type = new Vector<MultiPartDataElement>().getClass();
        info.name = "SiteListItems";
        break;

    default:break;
    }
}

@Override
public void setProperty(int index, Object value) 
{
    switch(index)
    {
    case 0:
        Name = value.toString();
        break;
    case 1:
        Id = Integer.parseInt(value.toString());
        break;
    case 2:
        SiteListItems = (Vector<MultiPartDataElement>)value;
    break;

    default:
        break;
    }
}

}

注意:如果我从客户端代码和Web服务中删除SiteListItems属性,一切正常。


上述对象中Array中使用的复杂类:

public class MultiPartDataElement extends IABaseKSoap2Serializable
{
public int Id;
public String Name;

// default constructor
public MultiPartDataElement()
{

}

// overloaded constructor
public MultiPartDataElement(int id, String name)
{
    Id = id;
    Name = name;
}

@Override
public Object getProperty(int arg0) 
{
    switch(arg0)
    {
    case 0:
        return Id;
    case 1:
        return Name;
    }

    return null;    
}

@Override
public int getPropertyCount() 
{
    return 2;
}

@Override
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.STRING_CLASS;
        info.name = "Name";
        break;
    default:break;
    }
}

@Override
public void setProperty(int index, Object value) 
{
    switch(index)
    {
    case 0:
        Id = Integer.parseInt(value.toString());
        break;
    case 1:
        Name = value.toString();
        break;
    default:
        break;
    }
}
}


将对象作为参数发送到.Net Web服务的代码:

public static boolean WriteCaseInfo()
{
    boolean status = false;

    CaseInformation caseInfo = new CaseInformation();
    caseInfo.Id = 2725;
    caseInfo.Name = "Craig M. Buck";

    caseInfo.SiteListItems = new Vector<MultiPartDataElement>();
    caseInfo.SiteListItems.add(new MultiPartDataElement(1, "CMB1"));
    caseInfo.SiteListItems.add(new MultiPartDataElement(2, "CMB2"));

    String methodName = "WriteCaseInfo";
    SoapObject request = new SoapObject(NAMESPACE, methodName);     
    request.addProperty("caseInfo", caseInfo);

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.bodyOut = request;
    envelope.dotNet = false;
    envelope.encodingStyle = SoapSerializationEnvelope.XSD;

    envelope.addMapping(IABaseKSoap2Serializable.NAMESPACE, "MultiPartDataElement", new MultiPartDataElement().getClass());
    envelope.addMapping(IABaseKSoap2Serializable.NAMESPACE, "CaseInformation", new CaseInformation().getClass());

    HttpTransportSE transport = new HttpTransportSE(WebAPIURL + CaseServicesURL);
    transport.debug = true;
    transport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");

    try
    {
        List<HeaderProperty> headers = BuildHeader();

        transport.call(NAMESPACE + methodName, envelope, headers);
        String requestDump = transport.requestDump;
        String soapDump = transport.responseDump;
        SoapObject response = (SoapObject) envelope.bodyIn;

        if(response != null)
            status = new Boolean(response.getProperty(0).toString());
    }
    catch(Exception e)
    {
        status = false;
    }

    return status;
}

从KSOAP请求转储:

<?xml version="1.0" encoding="utf-8"?><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><n0:WriteCaseInfo id="o0" c:root="1" xmlns:n0="http://www.medical.draeger.com/webservices/"><caseInfo i:type="n1:CaseInformation" xmlns:n1="http://www.medical.draeger.com/webservices/encodedTypes"><Name i:type="d:string">Craig M. Buck</Name><Id i:type="d:int">2725</Id><SiteListItems i:type="c:Array" c:arrayType="d:anyType[2]"><item i:type="n1:MultiPartDataElement"><Id i:type="d:int">1</Id><Name i:type="d:string">CMB1</Name></item><item i:type="n1:MultiPartDataElement"><Id i:type="d:int">2</Id><Name i:type="d:string">CMB2</Name></item></SiteListItems></caseInfo></n0:WriteCaseInfo></v:Body></v:Envelope>

注意:我认为问题在于,数组是定义为“anyTyp”而不是MultiPartDataElement - &gt; ......问题是我在这里做错了什么?

KSOAP的响应转储(通话后):

SoapException:服务器无法读取请求。 ---&GT; System.InvalidOperationException:XML文档中存在错误(1,828)。 ---&GT; System.InvalidCastException:无法将类型为System.Object []的对象分配给类型为Draeger.IT.Platform.Web.WebServices.MultiPartDataElement []

的对象

2 个答案:

答案 0 :(得分:0)

我遇到过类似的问题。您可能想尝试我的个人解决方案。

http://www.codeproject.com/Tips/222578/Android-access-to-NET-Web-Service-with-object-as-p

答案 1 :(得分:0)

你可以这样做:

int propertyCount = countryDetails.getPropertyCount();
ArrayList list = new ArrayList(propertyCount); 
lv_arr = new String[propertyCount]; 
for (int i = 0; i < propertyCount; i++) { 
  Object property = countryDetails.getProperty(i); 
  if (property instanceof SoapObject) { 
    SoapObject countryObj = (SoapObject) property; 
    String countryName = countryObj.getProperty("countryName").toString(); 
    list.add(countryName); 

  } 
} 

来自:Parsing ksoap2 response