如何在android上使用kso​​ap2调用WCF服务?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2589486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:27:00  来源:igfitidea点击:

How to call a WCF service using ksoap2 on android?

androidwcfksoap2

提问by Qing

Here is my code

这是我的代码

import org.ksoap2.*;
import org.ksoap2.serialization.*;
import org.ksoap2.transport.*;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class ksop2test extends Activity {
 /** Called when the activity is first created. */


 private static final String METHOD_NAME = "SayHello";
// private static final String METHOD_NAME = "HelloWorld";

 private static final String NAMESPACE = "http://tempuri.org";
// private static final String NAMESPACE = "http://tempuri.org";

 private static final String URL = "http://192.168.0.2:8080/HelloWCF/Service1.svc";
// private static final String URL = "http://192.168.0.2:8080/webservice1/Service1.asmx";

 final String SOAP_ACTION = "http://tempuri.org/IService1/SayHello";
// final String SOAP_ACTION = "http://tempuri.org/HelloWorld";
 TextView tv;
 StringBuilder sb;



 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  tv = new TextView(this);
  sb = new StringBuilder();
  call();
  tv.setText(sb.toString());
  setContentView(tv);
 }

 public void call() {
  try {

   SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

   request.addProperty("name", "Qing");

   SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
     SoapEnvelope.VER11);
   envelope.dotNet = true;
   envelope.setOutputSoapObject(request);


   HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
   androidHttpTransport.call(SOAP_ACTION, envelope);
   sb.append(envelope.toString() + "\n");//cannot get the xml request send
   SoapPrimitive result = (SoapPrimitive)envelope.getResponse();

   //to get the data
   String resultData = result.toString();
   // 0 is the first object of data 


   sb.append(resultData + "\n");
  } catch (Exception e) {
   sb.append("Error:\n" + e.getMessage() + "\n");
  }

 }

}

I can successfully access .asmx service, but when I try to call a wcf service the virtual machine said : Error: expected:END_TAG{http://schemas.xmlsoap.org/soap/envelope/}Body(position:END_TAGhttp://schemas.xmlsoap.org/soap/envelope/}s:Fault>@1:712 in java.io.InputStreamReader@43ba6798

我可以成功访问 .asmx 服务,但是当我尝试调用 wcf 服务时,虚拟机说:错误:预期:END_TAG{ http://schemas.xmlsoap.org/soap/envelope/}Body(position:END_TAGhttp:// /schemas.xmlsoap.org/soap/envelope/}s:Fault>@1:712 in java.io.InputStreamReader@43ba6798

How to print what the request send?

如何打印请求发送的内容?

Here is the wcf wsdl:

这是 wcf wsdl:

<wsdl:definitions name="Service1" targetNamespace="http://tempuri.org/">

<wsdl:types>
  <xsd:schema targetNamespace="http://tempuri.org/Imports">
  <xsd:import schemaLocation="http://para-bj.para.local:8080/HelloWCF/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
  <xsd:import schemaLocation="http://para-bj.para.local:8080/HelloWCF/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
  </xsd:schema>
</wsdl:types>

<wsdl:message name="IService1_SayHello_InputMessage">
  <wsdl:part name="parameters" element="tns:SayHello"/>
</wsdl:message>

<wsdl:message name="IService1_SayHello_OutputMessage">
  <wsdl:part name="parameters" element="tns:SayHelloResponse"/>
</wsdl:message>

<wsdl:portType name="IService1">
  <wsdl:operation name="SayHello">
    <wsdl:input wsaw:Action="http://tempuri.org/IService1/SayHello" message="tns:IService1_SayHello_InputMessage"/>
    <wsdl:output wsaw:Action="http://tempuri.org/IService1/SayHelloResponse" message="tns:IService1_SayHello_OutputMessage"/>
  </wsdl:operation>
</wsdl:portType>

<wsdl:binding name="BasicHttpBinding_IService1" type="tns:IService1">
  <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>

  <wsdl:operation name="SayHello">
   <soap:operation soapAction="http://tempuri.org/IService1/SayHello" style="document"/>

     <wsdl:input>
       <soap:body use="literal"/>
     </wsdl:input> 
     <wsdl:output>
       <soap:body use="literal"/>
     </wsdl:output>
  </wsdl:operation>
</wsdl:binding>

<wsdl:service name="Service1">

  <wsdl:port name="BasicHttpBinding_IService1" binding="tns:BasicHttpBinding_IService1">
    <soap:address location="http://para-bj.para.local:8080/HelloWCF/Service1.svc"/>
  </wsdl:port>
</wsdl:service>

</wsdl:definitions>

It uses <xsd:schema>in tag <wsdl:types>and the asmx uses <s:schema>in tag <wsdl:types>what's the difference?

<xsd:schema>在标签中使用<wsdl:types>和asmx<s:schema>在标签中使用有<wsdl:types>什么区别?

回答by Qing

finally I got it to work because the namespace missed a "/" in the end ,

终于我让它工作了,因为命名空间最后错过了一个“/”,

following is my code

以下是我的代码

package cn.qing.ksop2test;


import java.io.Writer;

import org.ksoap2.*;
import org.ksoap2.serialization.*;
import org.ksoap2.transport.*;
import org.xmlpull.v1.XmlSerializer;

import android.app.Activity;
import android.os.Bundle;
import android.util.Xml;
import android.widget.TextView;

public class ksop2test extends Activity {
/** Called when the activity is first created. */


private static final String METHOD_NAME = "HelloWorldRequest";
//  private static final String METHOD_NAME = "HelloWorld";

private static final String NAMESPACE = "http://tempuri.org/";
//  private static final String NAMESPACE = "http://tempuri.org";

private static final String URL = "http://192.168.0.2:8080/HelloWCF/Service1.svc";
//  private static final String URL = "http://192.168.0.2:8080/webservice1  /Service1.asmx";

final String SOAP_ACTION = "http://tempuri.org/IService1/HelloWorld";
//  final String SOAP_ACTION = "http://tempuri.org/HelloWorld";
TextView tv;
StringBuilder sb;
private XmlSerializer writer;



@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    tv = new TextView(this);
    sb = new StringBuilder();
    call();
    tv.setText(sb.toString());
    setContentView(tv);
}

public void call() {
    try {

        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

        request.addProperty("Name", "Qing");

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);


        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
        androidHttpTransport.call(SOAP_ACTION, envelope);
        SoapPrimitive result = (SoapPrimitive)envelope.getResponse();

        //to get the data
        String resultData = result.toString();
        // 0 is the first object of data 


        sb.append(resultData + "\n");
        } catch (Exception e) {
        sb.append("Error:\n" + e.getMessage() + "\n");
        }

    }

}

回答by Leo Moore

I'm using

我正在使用

private static final String SOAP_ACTION = "http://tempuri.org/IContact/GetContactCount";
private static final String METHOD_NAME = "GetContactCount";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://xxx.xxx.com/Contacts/ContactsService.Contacts.svc";

So maybe the problem is in your SOAP action.

所以问题可能出在您的 SOAP 操作中。

Also is the spelling on your method name correct ie AuthenticatdUser?

您的方法名称的拼写是否正确,即 AuthenticatdUser?

回答by Neelam Singh

Thanks Qing for your answer it's really help full for calling WCF service

感谢Qing的回答,对于调用WCF服务真的很有帮助

I would like to add this rectification for getting simple and complex output from web service after setting outputSoapObject into envelope,please correct me if i'm wrong

我想在将 outputSoapObject 设置为信封后添加此纠正以从 Web 服务获取简单和复杂的输出,如果我错了,请纠正我

envelope.setOutputSoapObject(requestSoapObject);

        // if its dotnet web service then make it true
        if (isDotNetWebService)
            envelope.dotNet = true;

        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
        androidHttpTransport.call(NAMESPACE + methodName, envelope);

        if (useBodyIn) // use bodyIn if service method returns string/int
                        // etc
        {
            /* Gives output from webservice */
            responseSoapObject = (SoapObject) envelope.bodyIn;
        } else // use getResponse() if service method returns objects or
                // array
        {
            /* Gives output from webservice */
            responseSoapObject = (SoapObject) envelope.getResponse();
        } 

回答by Shiraz Bhaiji

In "theory" wcf with basic http binding and asmx should work the same.

在具有基本 http 绑定和 asmx 的“理论” wcf 应该工作相同。

It could be something to do with how your WCF service is configured.

这可能与 WCF 服务的配置方式有关。

We get a similar problem if we configure TransferMode Streamed on the client and Buffered on the server. Although not sure if this is relevant in your case.

如果我们在客户端配置 TransferMode Streamed 并在服务器上配置 Buffered,我们会遇到类似的问题。虽然不确定这是否与您的情况相关。