locked
how to Consume an asmx webservice in Windows 8 Application ? RRS feed

  • Question

  • Hi ,

    I'm building a C# windows 8 app.

    I'm trying to POST to an asmx webservice some data.

    The method of the webservice accepts 4 arguments

    The first 3 are simple strings but the the fourth is a byte array .

    I tried to use the Httpclient with no success , I tried to use the HttpWebRequest with no success.

    I don't want to create a service reference and do it from there.

    I want using code to do that. 

    Does anyone has an example on how am I suppose to do it ?

    This is some of my tries. The below is not working

               

    The data field is the byte array which I got from here

    IRandomAccessStream fileStream = await FileForUpload.OpenAsync(FileAccessMode.Read);

                    var reader = new Windows.Storage.Streams.DataReader(fileStream.GetInputStreamAt(0));
                    await reader.LoadAsync((uint)fileStream.Size);

                    byte[] BytesToTranfer = new byte[fileStream.Size];
                    reader.ReadBytes(BytesToTranfer);
                    reader.Dispose();
                    reader = null;
                    fileStream = null;

    string data = Convert.ToBase64String(BytesToTranfer);

                                  

     DateTime ldtdate=DateTime.Now;

                    HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(myurl + "/Upload_Form");


                    System.Text.UTF8Encoding encoding = new UTF8Encoding();
                    byte[] postData = encoding.GetBytes("Code=" + app.Code + "&docRef="+ CurrentForm.DocumentReference + "&revNo="  + CurrentForm.RevisionNumber.ToString() + "&date=" + ldtdate.ToString() +  "&data=" + data);
                    httpReq.ContentType = "application/x-www-form-urlencoded";
                    httpReq.Method = "POST";

                    // convert the request to a steeam object and send it on its way
                    Stream ReqStrm = await httpReq.GetRequestStreamAsync();
                    ReqStrm.Write(postData, 0, postData.Length);
                    ReqStrm.Dispose();
                    ReqStrm = null;

                    WebResponse response = await httpReq.GetResponseAsync();
                    Stream stream = response.GetResponseStream();

    Can anyone help me on this or suggest me an alternative ? Just to remind you I don't want to add a service reference and the service is classic asmx  service.

    Appreciate any help you could give me.

    thank you

    Thursday, May 22, 2014 12:06 PM

Answers

  • Hi Zakkar,

    As I mentioned before, you can use HttpClient to do this but you'll have to write the code to create and parse the SOAP envelope.

    The easy in-box way to do this is to use Add Service Reference.

    You can simplify this on the server by exposing a REST end point.

    If you want to simplify the connection within your code you can factor the service reference calls into your own class with a simplified and consistent interface so the calling code doesn't need to know about the implementation details.

    --Rob

    • Marked as answer by zakkar Tuesday, June 3, 2014 7:04 AM
    Thursday, May 22, 2014 11:51 PM
    Moderator

All replies

  • Why don't you want to add a service reference? That is the easier and recommended way.

    See http://blogs.msdn.com/b/wsdevsol/archive/2012/12/21/help-me-how-do-i-connect-to-an-asmx-web-service.aspx

    That said, you should be able to use HttpClient by adding a SOAPAction header to the DefaultRequestHeaders collection then PostAsync()ing your soap package

    Thursday, May 22, 2014 1:12 PM
    Moderator
  • Hi  Rob ,

    I don't want to add a service ref. 

    Do you have some sample code with Httpclient ?

    thank you

    Thursday, May 22, 2014 1:14 PM
  • I don't have any sample code handy for this.

    Why don't you want to add a service ref?

    The only reason I can think of is that you want the learning exercise of doing it yourself, and my writing the code for you would defeat that :)

    Thursday, May 22, 2014 1:22 PM
    Moderator
  • I don't want to add endpoints and service refs in my app. I already know the solution with the service ref but then I will have to keep this plilosophy in my app for the rest of the services that I use. And trust me there are a lot with different endpoints.

    The easiest and more efficient way to do it because I will have to think other programmers that will take over the project is to have a specific way or writing the webservice calls.

    So far I used the HttpClient and passing and getting json formats . The code in my app is the same everywhere you look so for the other programmer it will be easy to create something like this if the case requires. 

    But I cannot make it work I mean don't know how to do it if I want to call an asmx and pass arguments which one of them is a byte array.

    Of course if I cannot do it I will go to this approach a service ref . But I have a lot of webservices and I want to avoid everytime to add it etc etc. Not mentioning what I told you above. To have the same code when calling a webservice so it can be easier for other programmers to maintain.

    Do you have any other approach ? Or Let me re-phrase that. Can the C# XAML windows 8 app support anything else for this case ? Or the one and only solution is the add service ref ??

    thank you Rob for your help

    I tried to implement the below but I'm getting an Internal Server Error

     string parameter = "Code=" +Code + "&docRef=" + CurrentForm.DocumentReference + "&revNo=" + CurrentForm.RevisionNumber.ToString() + "&date=" + ldtdate.ToString() + "&data=" + data;
                    byte[] bytes = Encoding.UTF8.GetBytes(parameter);

                    // instead of using HTTPWebRequest you should use HTTPClient
                    ByteArrayContent content = new ByteArrayContent(bytes);

                    content.Headers.Add("Content-Length", bytes.Length.ToString());
                    content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

                    HttpClient client = new HttpClient();
                    var responseMsg = await client.PostAsync(app.RCSIP, content);
                    var str = await responseMsg.Content.ReadAsStringAsync();

    Any ideas ???

    The asmx method accepts 4 arguments.

    this is the Http post

    POST /d----/mywebservice.asmx/Upload_Form HTTP/1.1
    Host: 10.2.4.6
    Content-Type: application/x-www-form-urlencoded
    Content-Length: length

    Code=string&docRef=string&revNo=string&date=string&data=string&data=string

    Does anyone see soemthing that is wrong ?

    • Edited by zakkar Thursday, May 22, 2014 3:46 PM
    Thursday, May 22, 2014 1:52 PM
  • Hi Zakkar,

    As I mentioned before, you can use HttpClient to do this but you'll have to write the code to create and parse the SOAP envelope.

    The easy in-box way to do this is to use Add Service Reference.

    You can simplify this on the server by exposing a REST end point.

    If you want to simplify the connection within your code you can factor the service reference calls into your own class with a simplified and consistent interface so the calling code doesn't need to know about the implementation details.

    --Rob

    • Marked as answer by zakkar Tuesday, June 3, 2014 7:04 AM
    Thursday, May 22, 2014 11:51 PM
    Moderator
  • Hi  Rob ,

    I 'm starting to thing that there's something wrong with the method because I already did it with SoapENvelop.

    Let me check some things and I will revert.

    Also I will expose a Rest end point and give it a try.

    thank you Rob . I'll get back to you

    Friday, May 23, 2014 5:18 AM
  • Hi Rob ,

    I did it finally with the add reference example.

    Thank you Rob for your help

    Tuesday, June 3, 2014 7:04 AM