Hosting webservices on WEC using gSOAP: Windows Phone 7.5 Mango Client Application

In the previous 2 articles (this and this one) I showed you how to create .NET C# based client applications consuming a webservice running on a Windows Embedded Compact device. In this blog post I will show you how to do the same, but then with a client application running on Windows Phone 7.5!

Convert RPC/encoded to RPC/literal

When you try to use the existing wsdl file in a silverlight solution for WP7 you won't be able to use the operations as described. It seems that the silverlight version doesn't support RPC/encoded soap and ignores those operations. It does support RPC/Literal soap style so we need to change the style from RPC/encoded to RPC/literal. This is actually really easy: Open the wsdl file and modify the input and output operations from

<soap:body use="encoded" ..../>

to

<soap:body use="literal" ..../>.

In XMLSpy:

You can see that the HelloWorld_Binding, the middle part, has changed. The input and output body styles have been modified from encoded to literal. That's basically all you need to change. This change in the wsdl file requires us to modify and rebuild the server and client code. Let's start with the server side.

Rebuild HelloWorldWebService solution

Open the existing "HelloWorldWebService.sln" solution we created in the previous blog post.

  1. Right-click the wsdl file and choose “compile”.
  2. Now recompile our (regenerated) header file: Right-click on the HelloWsdl.h file and choose "compile". This will re-generate a bunch of files as well.
  3. Finally; build the solution...

Oops! Unresolved externals... The reason for these is that we changed the message style and therefore we need to construct (or actually gSOAP needs to construct) the soap message slightly different.

In the HelloWorldWebservice solution open HelloWsdlMethods.cpp and modify the content to match the following:

// int ns1__HelloWorldOperation(struct soap*, char *name, char* &answer)
int ns1__HelloWorldOperation(struct soap*, char *name, struct ns1__HelloWorldOperationResponse &_param_1)
{
        printf("Hello my method\r\n");
        char* myName = {"Erwin"};
        //answer = myName;
        _param_1.answer = myName;
        return SOAP_OK;
}

//int ns1__UploadResource(struct soap*, char *resourceName, xsd__base64Binary resource, unsigned int resourceId, unsigned int &resourceId_)
int ns1__UploadResource(struct soap*, char *resourceName, xsd__base64Binary resource, unsigned int resourceId, struct ns1__UploadResourceResponse &_param_2)
{
        printf("Upload resource called (name: %s, id: %d", resourceName, resourceId);
        int size = resource.__size;
        return SOAP_OK;
}

I commented the original code and added new code to emphasize the code differences.

Windows Phone 7.5 (Mango) Client application

Now lets create a Windows Phone 7.5 client application. Make sure you have the Windows Phone SDK 7.1 installed. You need this to build applications for WP7/7.5.

Open Visual Studio 2010 Express for Windows Phone and create a new application (File | New Project). In the C# section "Silverlight for Windows Phone" choose "Windows Phone Application":

Choose TestWebServiceWP7 as the solution name and leave the other options as is. Select "OK" to create the solution.
I'll leave the sample as simple as possible just to illustrate how to consume a webservice running on a Windows Embedded Compact device. Drag 2 buttons on the content panel. Name the first button "Test" and the other "UploadImage". Something like:

Double-click the test button so we can enter the code behind. First thing we need to do is add our (Web)Service reference. In the solution explorer right click on the "Service Reference" and choose "Add Service Reference". Select HelloWsdl, created in the beginning of this article. You should be seeing something like:

As you can see I named the service "HelloWsdlService". Click "OK" to add the web service to our solution. Add the following code to complete the Test button implementation:

namespace TestWebServiceWP7
{
    public partial class MainPage : PhoneApplicationPage
    {
        private HelloWsdlService.HelloWorld_PortTypeClient service = null;

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Create service
            service = new HelloWsdlService.HelloWorld_PortTypeClient();

            // Event handler for asyn operation hello world
            service.HelloWorldOperationCompleted += new EventHandler<HelloWsdlService.HelloWorldOperationCompletedEventArgs>(HelloWorldOperation_Completed);
        }

        private void Test_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // Calling our webservice hello world
                service.HelloWorldOperationAsync("Erwin");
            }
            catch (Exception ex)
            {
                // Handle errors here
            }
        }

        void HelloWorldOperation_Completed(Object o, HelloWsdlService.HelloWorldOperationCompletedEventArgs args)
        {
            PageTitle.Text = args.Result.ToString();
        }
               
    }
}

As you can see I create the service class and the event handler which handles the HelloWorldOperation asynchroneously in the constructor. The button test code (Test_Click) calls HelloWorldOperation. Deploy your solution to either the WP7 emulator or to your Windows Phone device. Run the webservice code on the Topaz (as describer in the other articles) and run the application on the WP7 emulator or device.

To illustrate the complete solution check out this video showing me uploading and running the Windows Phone 7 application and the webservice on the Topaz. It is a recording of my desktop (I am using Cerdisp and Cerhost as an RDP solution to show the desktop of the Windows Embedded Compact device):

[video:www.youtube.com/watch?v=vhPtS-SmkB4 width:640 height:385 ratio:16/9]

If you have any questions please leave a comment below!

Comments

i have a problem with windows phone 7.5, i am call .wsdl web service in app but web method not return data.

please help me.