2

Android デバイスから KSOAP2 を使用して .NET Web サービスに送信される複合オブジェクトのプロパティで、「キャスト」エラーが発生します。プロパティは、複雑なオブジェクトの配列です。インターネット上のドキュメントは、単純なデータ型 (文字列、整数、日付など) を送受信するのに役立ちました。.NET Web サービスから複雑なオブジェクトの配列を読み取ることもできます。複雑なオブジェクトの配列を Web サービスに送り返すことができません。助けてください。ここに私が持っているものがあります:

環境: クライアント = 通信用の最新の KSOAP ライブラリを使用した Android 開発。サーバー = .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 プロパティを削除すると、すべてが機能します。


上記のオブジェクト内の配列で使用される複合クラス:

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>

注: 私が問題だと思うのは、配列がMultiPartDataElementではなく「anyTyp」として定義されているということです-> ...問題は、ここで何が間違っているのですか??

KSOAP からの応答ダンプ (呼び出し後):

SoapException: サーバーは要求を読み取ることができませんでした。---> System.InvalidOperationException: XML ドキュメントにエラーがあります (1, 828)。---> System.InvalidCastException: System.Object[] 型のオブジェクトを Draeger.IT.Platform.Web.WebServices.MultiPartDataElement[] 型のオブジェクトに割り当てることはできません

4

2 に答える 2

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); 

  } 
} 

from:ksoap2応答の解析

于 2012-02-01T12:59:19.243 に答える