android - 如何在 Android 中使用 WCF .SVC

标签 android .net wcf web-services ksoap2

我查阅了很多相关文档,但我无法使用这个 .svc 文件。 我对 .ASMX 文件没有任何问题。只有 SVC 我无法消费。真是非常非常非常压力......!我无法修改 WCF 部分。 我发布 WSDL 文件并尝试使用它:

WSDL

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
 xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
 xmlns:tns="http://tempuri.org/" 
 xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
 xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
 xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
 xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" 
 xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" 
 xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
 xmlns:wsa10="http://www.w3.org/2005/08/addressing" 
 xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" name="ValidateUser_wcf" 
 targetNamespace="http://tempuri.org/">
<wsp:Policy wsu:Id="WSHttpBinding_IValidateUser_wcf_policy">
<wsp:ExactlyOne>
<wsp:All>
<wsaw:UsingAddressing/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://URL/WebServices/validateuser.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://URL/WebServices/validateuser.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IValidateUser_wcf_ValidateUser_InputMessage">
<wsdl:part name="parameters" element="tns:ValidateUser"/>
</wsdl:message>
<wsdl:message name="IValidateUser_wcf_ValidateUser_OutputMessage">
<wsdl:part name="parameters" element="tns:ValidateUserResponse"/>
</wsdl:message>
<wsdl:portType name="IValidateUser_wcf">
<wsdl:operation name="ValidateUser">
<wsdl:input wsaw:Action="http://tempuri.org/IValidateUser_wcf/ValidateUser" message="tns:IValidateUser_wcf_ValidateUser_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IValidateUser_wcf/ValidateUserResponse" message="tns:IValidateUser_wcf_ValidateUser_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WSHttpBinding_IValidateUser_wcf" type="tns:IValidateUser_wcf">
<wsp:PolicyReference URI="#WSHttpBinding_IValidateUser_wcf_policy"/>
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="ValidateUser">
<soap12:operation soapAction="http://tempuri.org/IValidateUser_wcf/ValidateUser" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ValidateUser_wcf">
<wsdl:port name="WSHttpBinding_IValidateUser_wcf" binding="tns:WSHttpBinding_IValidateUser_wcf">
<soap12:address location="http://URL/WebServices/validateuser.svc"/>
<wsa10:EndpointReference>
<wsa10:Address>
http://URL/WebServices/validateuser.svc
</wsa10:Address>
</wsa10:EndpointReference>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

我的 Java #1。只是我复制了 xml,它是在嗅探有关原始 .NET 客户端的 HTTP POST 流量后出现的,我必须使用 Microsoft .Net Monitor 应用程序在 java 中复制它:

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

private static final String SOAP_ACTION_VALIDATION = "IValidateUser_wcf/ValidateUser";
private static final String VALIDATION_METHOD = "ValidateUser";
private final static String VALIDATION_URI = "http://URL/WebServices/validateuser.svc";

// only a1 node in the header i know, each other is unknown for me. I put them there only because i saw them in soap net client http post
String request = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
        "<s:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">"
        + "<s:Header>"
        //+ "<a:Action s:mustUnderstand=\"1\"> http://tempuri.org/IValidateUser_wcf/ValidateUser </a:Action>"
        + "<a1 xmlns=\"http://xxxx.xxx/\">"+testtoken+"</a1>"
        + "<a:MessageID> urn:uuid:c075fc4e-1e70-48f7-838b-9fa68e7aaad1 </a:MessageID>"
        + "<ActivityId CorrelationId=\"0d4e09eb-5d09-4617-a8e1-ec99415caab5\" xmlns=\"http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics\">"
        + "25adfad8-ab5f-474a-afe3-56941d4ad408"
        + "</ActivityId>"
        + "<a:ReplyTo> http://www.w3.org/2005/08/addressing/anonymous </a:ReplyTo>"
        + "<a:To s:mustUnderstand=\"1\"> http://URL/WebServices/validateuser.svc </a:To>"
        + "</s:Header>"
        + "<s:Body><ValidateUser xmlns=\"http://tempuri.org/\"><username>"+username+"</username><password>"+password+"</password></ValidateUser></s:Body>"
        + "</s:Envelope>";

    String result = CallWebService(VALIDATION_URI, NAMESPACE+VALIDATION_METHOD, request);   



public String CallWebService(String url, String soapAction, String envelope) {  

    final DefaultHttpClient httpClient = new DefaultHttpClient();
    // request parameters
    HttpParams params = httpClient.getParams();
    HttpConnectionParams.setConnectionTimeout(params, 10000);
    HttpConnectionParams.setSoTimeout(params, 15000);
    // set parameter
    HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true);

    // POST the envelope
    HttpPost httppost = new HttpPost(url);
    // add headers
    httppost.setHeader("soapaction", soapAction);
    httppost.setHeader("Content-Type", "text/xml; charset=utf-8");

    String responseString = "Nothingggg";
    try {

        // the entity holds the request
        HttpEntity entity = new StringEntity(envelope);
        httppost.setEntity(entity);

        // Response handler
        ResponseHandler<String> rh = new ResponseHandler<String>() {
            // invoked when client receives response
            public String handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {

                // get response entity
                HttpEntity entity = response.getEntity();                   

                // read the response as byte array
                StringBuffer out = new StringBuffer();
                byte[] b = EntityUtils.toByteArray(entity);

                // write the response byte array to a string buffer
                out.append(new String(b, 0, b.length));
                return out.toString();
            }
        };

         responseString = httpClient.execute(httppost, rh);

    } catch (Exception e) {
        e.printStackTrace();
        Log.d("me","Exc : "+ e.toString()); 

    }

    // close the connection
    httpClient.getConnectionManager().shutdown();
    return responseString;
}

Ksoap2 的我的 Java #2。在这种情况下,我收到此错误:

XmlPullParserException: unexpected type 
(position:END_DOCUMENT null@1:1 in 
java.io.InputStreamReader@blablabla)

但是我将 xml 字符串请求放入验证 xml 应用程序中,这样就可以了:

public String validateUser_WCF(String username, String password){

     String enctoken = TOKEN;
     String testtoken = TestTOKEN;      

     SoapSerializationEnvelope envelope = null;
     SoapObject request = null;
     HttpTransportSE httpTransportSE = null;

     try {
         request = new SoapObject(NAMESPACE, VALIDATION_METHOD);
         request.addProperty("username", username);
         request.addProperty("password", password);

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

         Element[] header = new Element[2];  
         header[0] = new Element().createElement(NAMESPACE, "To");
         header[0].setName("a1");                 
         header[0].addChild(Node.TEXT, VALIDATION_URI);

         header[1] = new Element().createElement(NAMESPACE_INFOCAD, "a1");                
         header[1].addChild(Node.TEXT, testtoken);

         envelope.headerOut = header;                                 

         httpTransportSE = new HttpTransportSE(VALIDATION_URI);

         httpTransportSE.debug = true;
         //httpTransportSE.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");

         httpTransportSE.call(NAMESPACE+SOAP_ACTION_VALIDATION, envelope);

         String response = (String) envelope.getResponse();
         Log.i("RESPONSE", response);
         return response;  

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally{
             Log.i(getClass().getSimpleName(),"requestDump : "+httpTransportSE.requestDump);
             Log.i(getClass().getSimpleName(),"responseDump : "+httpTransportSE.responseDump);
        }

我真的很希望有人能帮助我。我到达了一个死点......

最佳答案

我自己解决了(WCF绑定(bind)必须是basicHttpBinding,否则不起作用):

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

private static final String SOAP_ACTION_VALIDATION = "IValidateUser_wcf/ValidateUser";
private static final String VALIDATION_METHOD = "ValidateUser";

public boolean validateUser_WCF(String username, String password){

    SoapSerializationEnvelope envelope = null;
    SoapObject request = null;
    HttpTransportSE httpTransportSE = null;

    try {
        request = new SoapObject(NAMESPACE, VALIDATION_METHOD);
        request.addProperty("username", username);
        request.addProperty("password", password);

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

        //////////////////////////////                               
        // here you can add a HEADER element if you want
        Element[] header = new Element[1];  

        header[0] = new Element().createElement(NAMESPACE_INFOCAD, "a1");                
        header[0].addChild(Node.TEXT, "HeaderTextContent");

        envelope.headerOut = header;
        //////////////////////////////                               

        httpTransportSE = new HttpTransportSE(URL+VALIDATION_URI, 10*10000); // second parameter is timeout
        httpTransportSE.debug = true;
        httpTransportSE.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        httpTransportSE.call(NAMESPACE+SOAP_ACTION_VALIDATION, envelope);

        // if response is a simple text result, you can call SoapPrimitive, if not, you have to call SoapObject result and navigate in response's tree like an xml file
        SoapPrimitive result = (SoapPrimitive)envelope.getResponse();

        //To get the data.
        String textResult = result.toString();
        Log.i("textResult", textResult); 

        return true;

    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }finally{
                // here you can see in LOG what is request you send and what is response received
                Log.i(getClass().getSimpleName(),"requestDump : "+httpTransportSE.requestDump);
                Log.i(getClass().getSimpleName(),"responseDump : "+httpTransportSE.responseDump);
    }

    return false;
}

关于android - 如何在 Android 中使用 WCF .SVC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11160355/

相关文章:

java - ARCore:垂直平面上的随机对象旋转

c# - Resource.designer.cs 不在 Mono 中重新生成(Xamarin Studio)

java - fragment 兼容性问题:

c# - 将 Interlocked.CompareExchange 与类一起使用

c# - 是否有使用 basicHttpBinding 扩展 WCF 服务以允许 REST 服务与 JSON 通信的好方法?

c# - StartCoroutine 函数不适用于 android,但在 Unity 编辑器中运行良好

c# - FileShare.None 是否使线程等待文件流关闭?

c# - PushSharp - ios - StopAllServices() 挂起,没有错误

android - 从 JSON 对象中的字节数组获取图像到 Android 应用程序

wpf - 使用 Windows Workflow Foundation(WF) 作为表示规则引擎是否明智?