【问题标题】:Android - Send data to WCF Service hosted in WinformsAndroid - 将数据发送到 Winforms 中托管的 WCF 服务
【发布时间】:2013-07-29 17:25:03
【问题描述】:

我已通过正常渠道尝试解决此问题,但我似乎无法确定如何正确地将数据从我的 Android 应用程序发送到托管在我的 C# winforms 应用程序中的 WCF 库。

我已使用 Visual Studio 提供的 WCFClientTest 应用程序检查了该服务是否正确托管,并且一切正常。 当我调用此行时: androidHttpTransport.call(SOAP_ACTION, envelope);它似乎挂在 Android 应用中

我正在使用 ksoap2 尝试调用 WCF 服务,以 this link 作为教程。

Android 代码

private static final String METHOD_NAME = "Alive";
    private static final String NAMESPACE = "http://tempuri.org/";
    private static final String SOAP_ACTION 
                               = "http://tempuri.org/IDeviceHealth/Alive";

    //10.0.2.2 is the ip address for the device simulator.
    private static final String URL = "http://192.168.1.8:8733/DeviceHealth/HealthService/mex"; 

    //SOAP must be  the same version as the webservice.
    private static final int SOAP_VERSION = SoapEnvelope.VER12;

public void OnClickGoBtn(View v)
    {
        try 
        {
         SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

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

        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

        androidHttpTransport.call(SOAP_ACTION, envelope);
        Object result = envelope.getResponse();

        String resultData = result.toString();
        Log.d("WCF Response", resultData);          
        } 
        catch (IOException e) 
        {
          Log.d("WCF IO Error", e.toString());
        }
        catch (XmlPullParserException e) 
        {
            Log.d("XML Pull Error",e.toString());
        }
        catch(Exception e)
        {
            Log.d("General Exception", e.toString());
        }
    }

C# 服务器:

 <behaviors>
      <serviceBehaviors>
        <behavior name="MetadataBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service name="DeviceHealthService.DeviceHealth" behaviorConfiguration="MetadataBehavior">

        <endpoint address=""
                  binding="netTcpBinding"
                  contract="DeviceHealthService.IDeviceHealth"/>

        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange"/>

        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:10001"/>
            <add baseAddress="http://localhost:10002"/>
          </baseAddresses>
        </host>

      </service>
    </services>

public string Alive()
        {
            return "I am running";
        }

【问题讨论】:

    标签: c# android wcf


    【解决方案1】:

    您应该在 AsyncTask 中执行此操作,而不是在主线程中!从您的帖子来看,您似乎是从主线程中执行此操作的。

    您的代码的其他所有内容看起来都很正常。不过,我通常使用超时,但我看你没有。

    要注意的另一件事是,您将 URL 指向“localhost”,但您的 android 设备不知道 localhost 是什么。您应该指向 10.0.2.2。

    如果有帮助,这是我在一个使用基于 SOAP 的 WCF 服务的 Android 应用程序中使用的实用程序方法。请注意,我总是在 AsyncTask 中调用它,而不是在主线程中。

    public static String invokeSoapWebservice(String method, Bundle properties, int timeout) throws IOException, XmlPullParserException {
    
        String action = SOAP_ACTION + method;       
    
        System.out.println("Calling web method " + method);
    
        SoapObject request = new SoapObject(NAMESPACE, method);
    
        //Note - ORDER MATTERS HERE
        //If the web method takes employeeId, workSiteId, jobId in that order, 
        //they have to be added to the request in that order (what bullshit!)
    
        if(properties.containsKey("loginId")) {
            request.addProperty("loginId", properties.getInt("loginId"));
            System.out.println("loginId = " + properties.getInt("loginId"));
        }
    
        if(properties.containsKey("employeeId")) {
            request.addProperty("employeeId", properties.getInt("employeeId"));
            System.out.println("employeeId = " + properties.getInt("employeeId"));
        }
    
        if(properties.containsKey("workSiteId")) {
            request.addProperty("workSiteId", properties.getInt("workSiteId"));
            System.out.println("workSiteId = " + properties.getInt("workSiteId"));
        }
    
        if(properties.containsKey("jobId")) {
            request.addProperty("jobId", properties.getInt("jobId"));
            System.out.println("jobId = " + properties.getInt("jobId"));
        }
    
        if(properties.containsKey("laborDetailId")) {
            request.addProperty("laborDetailId", properties.getInt("laborDetailId"));
            System.out.println("laborDetailId = " + properties.getInt("laborDetailId"));
        }
    
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SOAP_VERSION);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);
    
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL, timeout);       
    
        androidHttpTransport.call(action, envelope);
        Object result = envelope.getResponse();
        String resultData = "null response";
        if(result != null) {
            resultData = result.toString();
        }
    
        System.out.println("Result for web method " + method + ": " + resultData);
    
        return resultData;
    }
    

    【讨论】:

    • 我将代码移到了 AsyncTask 中,当我调用 androidHttpTransport.call 时,我收到一个错误消息:org.xmlpull.v1.XmlPullParserException: unexpected type (position:END_DOCUMENT null@1:1 in java.lang. io.InputStreamReader@40d30448) 对此有何建议?如果这很重要,我使用的是 ksoap2 库的 2.1.2 版本。
    • 根据我的经验,当我遇到 XmlPullParserException 时,通常是因为服务器端出现异常,并且响应是无法正确解析的错误消息。如果要记录 WCF 服务的所有异常,则应先查看那里。如果没有,那么我强烈建议您记录 WCF 服务中的所有异常,可能使用 log4net 或 nlog 或类似的东西。 Web.Config 中还有一个选项可以从您的服务返回异常详细信息,您可能应该这样做。
    • P.S.您可能会遇到 404 响应,因为您指向的是“localhost”,而从您的 android 设备上,它在该 URL 上找不到任何东西。 404 响应也会导致 XMLPullParserException。
    • 我更改了 SOAP 参数和 URL,现在我得到一个内部服务器错误 500。XML 拉解析器错误似乎已经解决,我现在得到一个 IOException。
    • 这听起来像是服务器端错误。您绝对应该在服务器端记录错误,然后您只需查看日志即可了解 WCF 服务遇到异常的原因。
    猜你喜欢
    • 2012-07-10
    • 2014-08-25
    • 1970-01-01
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多