Комплексное размещение объектов Массив сложных объектов в .NET Web Service - PullRequest
2 голосов
/ 13 июня 2011

Я получаю ошибку «приведения» к свойству сложного объекта, которое отправляется веб-службе .NET с помощью KSOAP2 с устройства Android.Свойство представляет собой массив сложных объектов.Документация в Интернете помогла мне отправлять и получать простые типы данных (строки, целые числа, даты и т. Д.).Я даже могу прочитать массив сложных объектов из веб-службы .NET.Я просто не могу отправить массив сложных объектов в веб-сервис.Пожалуйста помоги.Вот что у меня есть:

Среда: Клиент = Разработка Android с использованием последней библиотеки KSOAP для связи.Сервер = .NET Web Service (Visual Studio 2008).Примечание: это НЕ WCF.

.NET Web Service:

[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;
    }
}

}

Примечание: Если удалить свойство 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:

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 -> ... вопрос в том, что я здесь делаю неправильно?

ОтветДамп из KSOAP (после вызова):

SoapException: серверу не удалось прочитать запрос.---> System.InvalidOperationException: в документе XML есть ошибка (1, 828).---> System.InvalidCastException: невозможно присвоить объект типа System.Object [] объекту типа Draeger.IT.Platform.Web.WebServices.MultiPartDataElement []

Ответы [ 2 ]

0 голосов
/ 01 февраля 2012

Вы можете сделать это:

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

  } 
} 

из: Парсинг ответа ksoap2

0 голосов
/ 09 июля 2011

У меня была похожая проблема. Возможно, вы захотите попробовать мое личное решение.

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

...