How to consume WCF .SVC in Android
Asked Answered
S

2

2

i red a lot of documents about, but i can't consume this .svc file. I've no problem with .ASMX file. Only SVC i'm not able to consume. It's very very very stressfull....! I can't modify WCF part. I post WSDL file and my try to consume it:

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>

My Java #1. Simply i've copied xml which come out after sniffed HTTP POST traffic about original .NET client, that i have to replicate in java, with Microsoft .Net Monitor application:

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;
}

My Java #2 by Ksoap2. In this case i got this error:

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

But i put xml string request in a validation xml application and it's ok:

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);
        }

I really really hope someone can help me. Im arrived in a dead point....

Subhuman answered 22/6, 2012 at 16:29 Comment(6)
I dont understand why people unrate question without saying why. I think i was clear in my questionSubhuman
At moment, i asked for setting basicHTTPbinding, and for my fortune they changed binding. Now all works fine but question is always unsolved with WS binding....Subhuman
Did you got the solution for your question. Please help me if yes. I too suffered by same problem #12929259Passerine
I got solution. Problem was in Binding. If WCF binding is setted WSHttpBinding, you can't consume it. Changing to basicHttpBinding i solved. By the way, i'll post on your post question my full code for consuming a WCF service. Give me a bit of time okSubhuman
Take a look to your post. I added my working codeSubhuman
Thq mate. I try it with my programPasserine
S
2

I solved by myself (WCF binding has to be basicHttpBinding, otherwise it doesn't work):

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;
}
Subhuman answered 18/10, 2012 at 13:25 Comment(5)
can i send one of the parameters as xml?Aggravation
as xml ? Maybe i didn't understand your question. SoapSerializationEnvelope object already builds an xml. Give me an example plsSubhuman
it builds an xml, but my wcf service method is like Methodname(strinputXML, strOutoutXML). So how can I set the soap object building xml into this strInputXml?Aggravation
if you want put SoapObject xml request and response in that method, you just have to take last 2 lines of code: "httpTransportSE.requestDump" and "httpTransportSE.responseDump". These calls give soap object in XML string format for your request and for server response.Subhuman
Wellcome. Take a look to xml request and response first by Log them. So you can say if your method can parse them without errors or strange behavioursSubhuman
L
2

Do you have control over WCF part?

The easiest way will be to update WCF bingding. Currently it is WSHttpBinding, That binding is way more complicated than *.asmx.

Check if it is possible to publish endpoint with basicHttpBinding binding.

http://msdn.microsoft.com/en-us/library/ms731361.aspx

That binding is compatible with *.asmx and you only will need to update URL in your java code to consume it.

Lumenhour answered 22/6, 2012 at 17:8 Comment(1)
I can't modify WCF. Only trying to consume. By the way, thx for your timeSubhuman
S
2

I solved by myself (WCF binding has to be basicHttpBinding, otherwise it doesn't work):

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;
}
Subhuman answered 18/10, 2012 at 13:25 Comment(5)
can i send one of the parameters as xml?Aggravation
as xml ? Maybe i didn't understand your question. SoapSerializationEnvelope object already builds an xml. Give me an example plsSubhuman
it builds an xml, but my wcf service method is like Methodname(strinputXML, strOutoutXML). So how can I set the soap object building xml into this strInputXml?Aggravation
if you want put SoapObject xml request and response in that method, you just have to take last 2 lines of code: "httpTransportSE.requestDump" and "httpTransportSE.responseDump". These calls give soap object in XML string format for your request and for server response.Subhuman
Wellcome. Take a look to xml request and response first by Log them. So you can say if your method can parse them without errors or strange behavioursSubhuman

© 2022 - 2024 — McMap. All rights reserved.