2013-07-29 52 views
0

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

我已经检查过使用Visual Studio提供的WCFClientTest应用程序正确承载了服务,并且所有事情都在这方面工作。 当我打电话给这条线: androidHttpTransport.call(SOAP_ACTION,envelope);它似乎挂在Android应用程序

我使用kso​​ap2尝试调用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"; 
     } 

回答

0

你应该在的AsyncTask内部这样做,而不是在主线程!从您的帖子看来,您似乎是从主线程完成此操作。

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

另一件需要注意的事情是,你正在将你的URL指向“localhost”,但你的android设备不知道本地主机是什么。您应该指向10.0.2.2。

如果有帮助,下面是我的一个Android应用程序中使用的实用程序方法,它使用基于SOAP的WCF服务。请注意,我总是在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; 
} 
+0

我感动的代码到的AsyncTask,当我打电话androidHttpTransport.call我得到一个错误回来:org.xmlpull.v1.XmlPullParserException:意外的类型(位置:END_DOCUMENT空@ 1:1 java.io. InputStreamReader @ 40d30448)有什么建议吗?如果有问题,我正在使用kso​​ap2库的2.1.2版本。 – Snuffaluffagus

+0

根据我的经验,当我遇到XmlPullParserException时,通常是因为服务器端存在异常,并且响应是错误消息,无法正确解析。如果你正在记录你的WCF服务的所有异常,你应该先看看那里。如果不是这样,那么我强烈建议你记录WCF服务中的所有异常,比如log4net或nlog或类似的东西。在Web.Config中还有一个选项可以从您的服务中返回异常详细信息,您应该这样做。 – Jim

+0

P.S.你可能正在404响应,因为你指向“本地主机”,并从你的Android设备,它无法找到任何在该网址。 404响应也会导致XMLPullParserException。 – Jim