使用带有复杂对象的KSoap2调用WCF服务. WCF收到空值 [英] Calling WCF Service with KSoap2 with complex objects. WCF receives empty values

查看:68
本文介绍了使用带有复杂对象的KSoap2调用WCF服务. WCF收到空值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WCF服务,可以接收和返回comples对象,我需要在Android中调用它.我已经阅读了很多有关如何使用Ksoap的知识,目前我的应用正在调用WCF服务,但是WCF服务在请求对象的属性中接收到空值.

I have a WCF service that receive and returns comples objects and I need to call it in Android. I have readed a lot of how to work with Ksoap and at the moment my app is calling the WCF service but WCF service receives empty values in the properties of the request object.

WCF服务

[OperationContract]
WrAsignChkResponse CheckTrsRequest(WrAsignChkModel WrAsignData);

//Request and response objects in .Net
public class WrAsignChkModel
{
    public string Arg1 { get; set; }
    public string Arg2 { get; set; }
    public string Arg3 { get; set; }
    public string Arg4 { get; set; }
}


public class WrAsignChkResponse
{
    public int ResponseCode { get; set; }
    public string Message { get; set; }
    public string RequestStatus { get; set; }
    public string RequestTimeStamp { get; set; }
}

使用KSoap2的Android代码

private SoapSerializationEnvelope getWebServiceEnvelope(){
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.dotNet = true;
    envelope.implicitTypes = true;
    return envelope;
}

private void callWebService(){
    SoapObject body = new SoapObject(this.callHeader.getNamespace(), this.callHeader.getMethodName());
    if (this.parameters != null && !this.parameters.isEmpty()) {
        for (PropertyInfo param : this.parameters) {
            body.addProperty(param);
        }
    }
    SoapSerializationEnvelope envelope = this.getWebServiceEnvelope();
    envelope.setOutputSoapObject(body);
    envelope.addMapping(callHeader.getNamespace(), "WrAsignData", WrAsignChkModel.class);

    HttpTransportSE transport = new HttpTransportSE(this.webServiceUrl, this.timeOut);
    transport.debug = true;
    transport.call(callHeader.getSoapAction(), envelope);
    this.soapResponse = envelope.getResponse();
}

我在Android中也拥有实现KVM可序列化的请求对象.

Also I have the request Object in Android that implements KVM Serializable.

public class WrAsignChkModel implements KvmSerializable {
    private String Arg1;
    private String Arg2;
    private String Arg3;
    private String Arg4;

    //Getter and setters

    @Override
    public Object getProperty(int index) {
        switch(index)
        {
            case 0:
                return Arg1;
            //...
        }
        return null;
    }

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

    @Override
    public void setProperty(int index, Object value) {
        switch(index)
        {
            case 0:
                Arg1 = value.toString();
                break;
            //...
            default:
                break;
        }
    }

    @Override
    public void getPropertyInfo(int index, Hashtable properties, PropertyInfo info) {
        switch(index)
        {
            case 0:
                info.type = PropertyInfo.STRING_CLASS;
                info.name = "Arg1";
                break;
            //...
            default:
                break;
        }
    }
}

HttpTransportSE请求转储 通过此请求,WCF服务正在WrAsignData对象中接收空值

HttpTransportSE request dump With this request the WCF service is receiving empty values in the WrAsignData object

<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>
<CheckTrsRequest xmlns="http://tempuri.org/">
<WrAsignData>
    <Arg1>XXXX</Arg1>
    <Arg2>XXXX</Arg2>
    <Arg3>XXXX</Arg3>
    <Arg4>XXXX</Arg4>
</WrAsignData>
</CheckTrsRequest>
</v:Body>
</v:Envelope>

我已经使用Windows Forms测试应用程序对Web服务进行了测试,并且捕获了该应用程序通过Wireshark发送的XML,并且发现它的参数名称空间有所不同.

I have tested the web service with a Windows Forms test application and I have captured the XML that this app is sending with wireshark and I see that it's a difference in the namespace of the parameter.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
    <CheckTrsRequest xmlns="http://tempuri.org/">
        <WrAsignData xmlns:a="http://schemas.datacontract.org/2004/07/Models.TrsApiModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <a:Arg1>XXXX</a:Arg1>
            <a:Arg2>XXXX</a:Arg2>
            <a:Arg3>XXXX</a:Arg3>
            <a:Arg4>XXXX</a:Arg4>
        </WrAsignData>
    </CheckTrsRequest>
    </s:Body>
</s:Envelope>

Internet上没有很多有关如何与KSoap2一起正常工作的信息,我也找不到解决方案.有人可以帮我吗?

There is no a lot of information on the internet of how to work properly with KSoap2 and I don't find the solution of this. Can anybody help me with this?

推荐答案

经过数小时的调查,我已经解决了它.在相同情况下,我将发布答案以帮助他人.

I have solved it after hours of investigation. I'll post the answer to help others in the same case.

使用SoapUI,我已经看到要发送的名称空间和XML,然后尝试使用KSoap2生成类​​似的内容.

Using SoapUI I have seen the namespaces and the XML to send and then trying with KSoap2 generating something similar to that.

在我的课堂上,我在getPropertyInfo方法中添加了名称空间.所有属性都使用相同的名称空间,这将生成一个XML,其中所有标签中都包含该名称空间.与我在问题中提到的XML不同.没关系,而且可以兼容.

In my class I have added the namespace in the getPropertyInfo method. It is the same namespace to all properties and this will generate an XML with the namespace in all tags. Different than the XML that I have mentioned in my question. But it's ok and is compatible.

@Override
public void getPropertyInfo(int index, Hashtable properties, PropertyInfo info) {
    switch(index)
    {
        case 0:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "Arg1";
            info.namespace = "http://schemas.datacontract.org/2004/07/Models.TrsApiModel"
            break;
        //...
        default:
            break;
    }
}

然后在我的课堂上,我添加了一种生成SoapObject的方法.名称空间与对象内部的属性不同.

Then in my class I have added a method to generate a SoapObject. The namespace is not the same as the properties inside the object.

public SoapObject getSoapRequest(String nameSpace, String name){
    SoapObject soapRequest = new SoapObject(nameSpace, name);
    for(int i = 0; i < this.getPropertyCount(); i++){
        PropertyInfo prp = new PropertyInfo();
        this.getPropertyInfo(i, null, prp);
        prp.setValue(this.getProperty(i));
        soapRequest.addProperty(prp);
    }
    return soapRequest;
}

否则,您有要发送的SoapObject,您必须使用addSoapObject方法将int添加到Body SoapObject.

Onse you have the SoapObject to send you have to add int to the Body SoapObject with addSoapObject method.

SoapObject body = new SoapObject(this.callHeader.getNamespace(), this.callHeader.getMethodName());
//soapObj is an instance using the getSoapRequest() method mentioned in my piece of code
body.addSoapObject(soapObj);
SoapSerializationEnvelope envelope = this.getWebServiceEnvelope();
envelope.setOutputSoapObject(body);

使用该代码,所有内容似乎都可以正常运行,但并不完全.我已经体验到服务器可以很好地接收某些参数,但并非所有参数都可以.还有一点棘手的事情是,对象属性必须与SoapUi请求中的参数具有相同的顺序.因此,您必须修改对象方法中的开关,以使索引的顺序与在SoapUI XML请求中看到的顺序相同.

With that code everything seems to work but not completely. I have experienced that some of the parameters are received well by the server but not all of them. One more tricky thing is that the object properties must be in the same order as the parameters in the SoapUi request. So you have to modify the switches in the methods of the object to have the index in the same order as you can see in the SoapUI XML request.

与索引注意顺序相同的方法

Methods to pay attention at with the index to have the same order

public Object getProperty(int index)
public void setProperty(int index, Object value)
public void getPropertyInfo(int index, Hashtable properties, PropertyInfo info)

我花了很多时间才能发现WCF如何如此详细地接收正确的参数.因此,希望我的回答对遇到同样问题的人有所帮助.

It takes me a lot of time to discover how WCF is such kind of detailed to receive the correct parameters. So hope my answer will help someone with same problems.

这篇关于使用带有复杂对象的KSoap2调用WCF服务. WCF收到空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆