ksoap2 将复杂对象数组发送到 WCF 服务

Posted

技术标签:

【中文标题】ksoap2 将复杂对象数组发送到 WCF 服务【英文标题】:ksoap2 Sending array of complex objects to WCF service 【发布时间】:2016-02-11 00:52:08 【问题描述】:

我正在尝试将一组复杂对象从 android 客户端发送到我的 WCF 服务。 我使用http://seesharpgears.blogspot.ru/2010/10/web-service-that-returns-array-of.html 作为接收复杂对象数组的示例,并且效果很好。但是我不明白如何发送这个数组。

我正在使用 kmvserializable 作为对象: 公共类 RatingHttps 实现 KvmSerializable

public int CIsso;

public int RatingIsso;

public long RatingDate;

public String RatingExt;

public RatingHttps() super();

public RatingHttps(int CIsso, int RatingIsso, long RatingDate, String RatingExt) 
    this.CIsso = CIsso;
    this.RatingIsso = RatingIsso;
    this.RatingDate = RatingDate;
    this.RatingExt = RatingExt;


@Override
public Object getProperty(int i) 
    Object property = null;
    switch (i) 
        case 0:
            property = this.CIsso;
            break;
        case 1:
            property = this.RatingDate;
            break;
        case 2:
            property = this.RatingExt;
            break;
        case 3:
            property = this.RatingIsso;
            break;
    
    return property;


@Override
public int getPropertyCount() 
    return 4;


@Override
public void setProperty(int i, Object o) 
    switch (i) 
        case 0:
            this.CIsso = Integer.parseInt(o.toString());
            break;
        case 1:
            this.RatingDate = Long.parseLong(o.toString());
            break;
        case 2:
            this.RatingExt = o.toString();
            break;
        case 3:
            this.RatingIsso = Integer.parseInt(o.toString());
            break;

    

private static final String NAMESPACE = "http://schemas.datacontract.org/2004/07/Ais7UpdateServer";

@Override
public void getPropertyInfo(int i, Hashtable hashtable, PropertyInfo propertyInfo) 
    switch (i) 
        case 0:
            propertyInfo.type = PropertyInfo.INTEGER_CLASS;
            propertyInfo.name = "CIsso";
            propertyInfo.setNamespace(NAMESPACE);
            break;
        case 1:
            propertyInfo.type = PropertyInfo.LONG_CLASS;
            propertyInfo.name = "RatingDate";
            propertyInfo.setNamespace(NAMESPACE);
            break;
        case 2:
            propertyInfo.type = PropertyInfo.STRING_CLASS;
            propertyInfo.name = "RatingExt";
            propertyInfo.setNamespace(NAMESPACE);
            break;
        case 3:
            propertyInfo.type = PropertyInfo.INTEGER_CLASS;
            propertyInfo.name = "RatingIsso";
            propertyInfo.setNamespace(NAMESPACE);
            break;
        default: break;
    

我就是这样使用它的:

List<RatingHttps> ratings = new ArrayList<>();
        RatingHttps rating = new RatingHttps();
        rating.CIsso = 1;
        rating.RatingIsso = 2;
        rating.RatingExt = "LOL";
        rating.RatingDate = 3;
        ratings.add(rating);
        rating = new RatingHttps();
        rating.CIsso = 10;
        rating.RatingIsso = 20;
        rating.RatingExt = "OLOLO";
        rating.RatingDate = 30;
        ratings.add(rating);
            //cr.moveToNext();


        //request = GetSoapObject(METHOD_NAME[2]);
        request = new SoapObject(NAMESPACE, METHOD_NAME[2]);

        //envelope = GetEnvelope(request);
        request.addProperty("id", resultId.toString());
        //PropertyInfo pi = new PropertyInfo();
        //pi.setName("ratings");
        //pi.setValue(ratings);
        //pi.setType(ratings.getClass());

        //request.addProperty(pi);
        request.addProperty("ratings", ratings);

        //envelope.addMapping(NAMESPACE, ratings.getClass().getSimpleName(), ratings.getClass());
        envelope.addMapping(NAMESPACE, "ArrayOfRatingHttps", RatingHttps.class);
        SoapObject count = (SoapObject) SecureConnect(SOAP_ACTION[2], request, envelope);

安全连接:

private Object SecureConnect(String soapAction, SoapObject request, SoapSerializationEnvelope envelope) 
    try 
        if(request != null) 
            envelope.setOutputSoapObject(request);
            envelope.dotNet = true;
        
        HttpsTransportSE androidHttpsTransport = new HttpsTransportSE(host, port, subFile, 20000);
        androidHttpsTransport.call(soapAction, envelope);
        return envelope.getResponse();
     catch (Exception e) 
        result = e.toString();
        Log.d("Tag", "Ошибка: " + e.toString());
        return null;
    

我尝试过使用数组,比如 Rating[].. 和 Vector,但这不起作用。 我不知道该怎么办!也许有人有一些例子如何做到这一点?请帮忙。

【问题讨论】:

【参考方案1】:

在互联网上搜索了几个小时后,我终于找到了可行的示例。如果您有同样的问题,请确保您发送正确的 xml 文件。首先,我将必须接收的 xml 文件与服务器上的 xml 文件进行匹配。当我发现它们是相同的时,我在标签中发现了一个错误,我将在代码中展示我是如何做到的: 我的 RatingHttps 课程与我的问题相同; 例如初始化我的类:

List<RatingHttps> rating = new ArrayList<>();
        RatingHttps ratings = new RatingHttps();
        ratings.CIsso = 1;
        ratings.RatingIsso = 2;
        ratings.RatingExt = "LOL";
        ratings.RatingDate = 3;
        rating.add(ratings);

接下来,请求:

request = new SoapObject(NAMESPACE, METHOD_NAME[2]);
        SoapObject ratingRequest = new SoapObject(NAMESPACE, "ArrayOfRatingHttps");
        request.addProperty("id", resultId.toString());
        PropertyInfo pi = new PropertyInfo();
        pi.setName("ratings");
        pi.setValue(ratingRequest);
        pi.setType("ArrayOfRatingHttps");
        request.addProperty(pi);

        for(int i = 0; i < rating.size(); i++) 
            SoapObject rate = new SoapObject(RatingHttps.NAMESPACE, RatingHttps.class.getSimpleName());

            //Добавляем значения RatingHttps в xml запрос
            rate.addProperty(getPropInfo(rating.get(i).getAttributeName(0), rating.get(i), rating.get(i).getAttributeType(0)));
            rate.addProperty(getPropInfo(rating.get(i).getAttributeName(1), rating.get(i), rating.get(i).getAttributeType(1)));
            rate.addProperty(getPropInfo(rating.get(i).getAttributeName(2), rating.get(i), rating.get(i).getAttributeType(2)));
            rate.addProperty(getPropInfo(rating.get(i).getAttributeName(3), rating.get(i), rating.get(i).getAttributeType(3)));

            ratingRequest.addSoapObject(rate);
        
        envelope.addMapping(NAMESPACE, RatingHttps.class.getSimpleName(), RatingHttps.class);
HttpsTransportSE androidHttpsTransport = new HttpsTransportSE(host, port, subFile, 20000);
        androidHttpsTransport.call(soapAction, envelope);

我在 xsd 文件中为数组找到“ArrayOfRatingHttps”的位置。如果您有 wcf 服务,您可以在地址“https://your_address?xsd=xsd2”中找到它。另外我实现了一个getPropInfo函数,代码如下:

private PropertyInfo getPropInfo(String name, RatingHttps rating, Object type) 
    PropertyInfo pi = new PropertyInfo();
    pi.setName(name);
    pi.setValue(rating.getCIsso());
    pi.setType(type);
    pi.setNamespace(RatingHttps.NAMESPACE);
    return pi;

我还在 xsd 文件中找到了我的服务作为 targetNamespace 的 NAMESPACE。就是这样,现在我可以发送一个复杂对象数组。希望有一天它会对某人有所帮助......

【讨论】:

以上是关于ksoap2 将复杂对象数组发送到 WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

Ksoap2 Android - 如何为复杂对象的子属性指定命名空间?

使用 KSOAP2 从 Android 向 WCF 发送数据

使用 ksoap2 使用 WCF 服务

将对象从Windows Mobile 6应用程序发送到wcf服务时,对象属性设置为null

将数据(复杂数据/原始数据)发送到服务并获取响应(复杂数据/原始数据)的最佳方式(WCF 或 WEB API)

将复杂对象传递到 WCF Rest 服务