Creating a SOAP web service

1,255 views
Skip to first unread message

devqu...@yahoo.com

unread,
Apr 16, 2012, 3:15:20 PM4/16/12
to ServiceStack .NET Open Source REST Web Services Framework
Hi,

I am learning web-services and working on hosting a SOAP service on
Linux. I researched and came across following frameworks for creating/
hosting web-services:

1) gSOAP in C++.
2) Axis in Java
3) ServiceStack in .Net.

Though I have programmed in all these languages I got inclined towards
ServiceStack as I have used Mono on Linux.
I started with the HelloWorld sample and created a console type
application. I used AppHostHttpListenerBase for the endpoint.
Service is getting hosted properly on Linux using Mono but when I go
on the metadata page of the service and click on SOAP 1.2 I get a "Not
implemented
exception". As per my current understanding hosted service is going to
be available as both SOAP and REST. Is that right?
I would appreciate if anybody let me know what I am missing here or
could provide an example of how to create a SOAP endpoint using
ServiceStack.
Also, has anybody heard of other web-service frameworks that I
mentioned above? After I am done with this sample app I would like to
start
a bigger application that supports complex-types, polymorphic types.
I'd appreciate responses.

Thanks.

Demis Bellot

unread,
Apr 16, 2012, 3:51:18 PM4/16/12
to servic...@googlegroups.com
Unfortunately Mono has an incomplete version of XsdSchema meaning it's not able to generate the WSDL (used to code-gen the SOAP client proxies) on Mono.
Creating code-gen'ed client proxies from WSDLs is a design-time process 

Although Mono still supports the SOAP endpoints at runtime i.e. the Soap11ServiceClient/Soap12ServiceClient allow you to call SOAP services (just like every other https://github.com/ServiceStack/ServiceStack/wiki/C%23-client) without needing to use the WSDL, since it makes use of the existing DTO types to provide a typed API without any code-gen. The preferred approach is to not use code-gen (since its an un-necessary post build step) but rather to re-use of the clean generic service clients + server DTOs.

If you prefer you can still view your web services WSDL by deploying on Windows IIS/ASP.NET where you can make use of VS.NET to generate the client proxies. You can then copy the dlls to Linux/Mono and run it there.
This is how the SOAP example were deployed (Note: www.serviecstack.net is hosted on CentOS/Mono):

Cheers,


devqu...@yahoo.com

unread,
Apr 17, 2012, 9:43:08 AM4/17/12
to ServiceStack .NET Open Source REST Web Services Framework

Hi Demis,




Thanks for the reply. As per your suggestion I moved to building the
binaries on Windows. I have the following classes available:


 class Program
    {
        private static readonly string ListeningOn = "ip + port";

        //HttpListener Hosts
        static void Main(string[] args)
        {
            var appHost = new AppHost();
            appHost.Init();
            appHost.Start(ListeningOn);

            Console.WriteLine("Started listening on: " + ListeningOn);
            Console.WriteLine("AppHost Created at {0}, listening on
{1}",
                DateTime.Now, ListeningOn);

            Console.WriteLine("ReadKey()");
            Console.ReadKey();
        }
    }

public class AppHost :
ServiceStack.WebHost.Endpoints.AppHostHttpListenerBase
    {
        public AppHost() : base("webservice",
typeof(HelloService).Assembly) { }
        public override void Configure(Funq.Container container)
        {
            SetConfig(new EndpointHostConfig
            {
                GlobalResponseHeaders =
                {
                    { "Access-Control-Allow-Origin", "*" },
                    { "Access-Control-Allow-Methods", "GET, POST" },
                },

                MarkdownSearchPath = "/debug/bogus/",
                AllowJsonpRequests = false,
                DebugMode = true,
                WriteErrorsToResponse = true,
                WsdlServiceNamespace = "SoapPrototype",
                DefaultContentType =
ServiceStack.Common.Web.ContentType.Soap12,
            });

            Routes
             .Add<Hello>("/hello")
             .Add<Hello>("/hello/{Name}");
        }
    }

    public class Hello
    {
        public string Name { get; set; }
    }

    public class HelloResponse
    {
        public string Result { get; set; }
    }

    public class HelloService : IService<Hello>
    {
        public object Execute(Hello request)
        {
            return new HelloResponse
            {
                Result = "Hello, " + request.Name
            };
        }
    }

I wrote a WCF client by hand using the DataContract way

namespace TestWCF
{
    class Program
    {
        private static TestWCF.Test.IHello helloChannel;

        static void Main(string[] args)
        {
            ChannelFactory<TestWCF.Test.IHello> channelFactory = null;

            string endpointUri = @"http://xx.xx.xx.xx:48666/soap12/";

            BasicHttpBinding binding = new BasicHttpBinding();
            channelFactory = new
ChannelFactory<TestWCF.Test.IHello>(binding, new
EndpointAddress(endpointUri));
            helloChannel = channelFactory.CreateChannel();
            TestWCF.Test.Hello request = new TestWCF.Test.Hello();
            request.Name = "chal jaaye";
            TestWCF.Test.HelloResponse response = new
TestWCF.Test.HelloResponse();
            response = helloChannel.Execute(request);
            response.Result.ToString();
        }
    }

class Test
    {
        [DataContract()]
        public class HelloResponse
        {
            [DataMember]
            public string Result;
        }

        [DataContract()]
        public class Hello
        {
            [DataMember]
            public string Name;
        }

        [ServiceContract()]
        public interface IHello
        {
            [OperationContract]
            HelloResponse Execute(Hello request);
        }
    }
}


I am interested in using a standalone app and don't want to go the
ASP.NET. When I start the client for consuming the service I get the
following exception:

The content type application/json of the response message does not
match the content type of the binding (text/xml; charset=utf-8).
If using a custom encoder, be sure that the IsContentTypeSupported
method is implemented properly. The first 807 bytes of the response
were: '{
"ResponseStatus":{
 "ErrorCode":"NotImplementedException",
 "Message":"The method or operation is not implemented.",
 "StackTrace":"   at
ServiceStack.WebHost.Endpoints.Support.EndpointHandlerBase.ProcessRequest(IHttpRequest
httpReq, IHttpResponse httpRes, String operationName) in C:\\src\
\ServiceStack\\src\\ServiceStack\\WebHost.EndPoints\\Support\
\EndpointHandlerBase.cs:line 52\n   at
ServiceStack.WebHost.Endpoints.AppHostHttpListenerBase.ProcessRequest(HttpListenerContext
context) in C:\\src\\ServiceStack\\src\\ServiceStack\\WebHost.EndPoints
\\AppHostHttpListenerBase.cs:line 58\n   at
ServiceStack.WebHost.Endpoints.Support.HttpListenerBase.ListenerCallback(IAsyncResult
asyncResult) in C:\\src\\ServiceStack\\src\\ServiceStack\
\WebHost.EndPoints\\Support\\HttpListenerBase.cs:line 197"
}
}
'.
Is hosting on ASP.NET/IIS the only way? I apologize if the answer is
obvious as I have little knowledge of ASP.Net. How would the service
host/work when I copy the binaries on Linux. Would I need an
equivalent of IIS on Linux like Apache running?
I would appreciate if you could more information on this. For the web-
service to be SOAP I am using the 'DefaultContentType =
ServiceStack.Common.Web.ContentType.Soap12' and using
'Soap12' in the endpoint of client. Would this make the endpoint to be
soap? Apologies if I am asking too many obvious questions. Thanks for
the help.

Regards.


On Apr 16, 3:51 pm, Demis Bellot <demis.bel...@gmail.com> wrote:
> Unfortunately Mono has an incomplete version of XsdSchema meaning it's not
> able to generate the WSDL (used to code-gen the SOAP client proxies) on
> Mono.
> Creating code-gen'ed client proxies from WSDLs is a design-time process
>
> Although Mono still supports the SOAP endpoints at runtime i.e. the
> Soap11ServiceClient/Soap12ServiceClient allow you to call SOAP services
> (just like every otherhttps://github.com/ServiceStack/ServiceStack/wiki/C%23-client) without
> needing to use the WSDL, since it makes use of the existing DTO types to
> provide a typed API without any code-gen. The preferred approach is to not
> use code-gen (since its an un-necessary post build step) but rather to
> re-use of the clean generic service clients + server DTOs.
>
> If you prefer you can still view your web services WSDL by deploying
> on Windows IIS/ASP.NET where you can make use of VS.NET to generate the
> client proxies. You can then copy the dlls to Linux/Mono and run it there.
> This is how the SOAP example were deployed (Note:www.serviecstack.netis
> hosted on CentOS/Mono):http://www.servicestack.net/ServiceStack.Examples.Clients/Soap12.aspx
> source code at:https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src...
>
> Cheers,
>
> On Mon, Apr 16, 2012 at 3:15 PM, devquer...@yahoo.com
> <devquer...@yahoo.com>wrote:

Demis Bellot

unread,
Apr 17, 2012, 9:59:18 AM4/17/12
to servic...@googlegroups.com
Is hosting on ASP.NET/IIS the only way?  

For SOAP Yes, its only supported on ASP.NET Hosts.
However you can easily convert between a HttpListener and ASP.NET host app as seen at: http://www.servicestack.net/mythz_blog/?p=785

How would the service host/work when I copy the binaries on Linux. Would I need an equivalent of IIS on Linux like Apache running?

For ASP.NET Hosts you would need to configure it to run in Apache/mod_mono or alternatively using something like Nginx/MonoFastCgi.

Note: You only need the WSDL to code-gen your client proxies, you can still call the SOAP endpoints without code-gen clients (i.e. the recommended approach) by just using the built-in generic service clients, e.g:

You are using SOAP when you HTTP POST a SOAP Envelope request to a SOAP endpoint which for servicestack is located at /api/soap11/{OperationName} or /api/soap12/{OperationName}
This is what the generic Soap11ServiceClient/Soap12ServiceClient does for you.

Cheers,

Erik van den Berg

unread,
Apr 17, 2012, 10:25:26 AM4/17/12
to servic...@googlegroups.com
Woow, it's a bit over my head and would love to see something like this in C#, the async part means that it can handle multiple request at the same time? correct?

Demis Bellot

unread,
Apr 17, 2012, 10:30:56 AM4/17/12
to servic...@googlegroups.com
All the examples on https://github.com/ServiceStack/ServiceStack.Examples/ are in C# and the Starter Templates show the same app in each of the different host configurations: https://github.com/ServiceStack/ServiceStack.Examples/tree/master/src/StarterTemplates

the async part means that it can handle multiple request at the same time? correct?

No it can already handle multiple requests at the same time. Async means its non-blocking i.e. no threads are blocked whilst waiting for an IO Response.

Cheers,

devqu...@yahoo.com

unread,
Apr 17, 2012, 4:35:31 PM4/17/12
to ServiceStack .NET Open Source REST Web Services Framework
Hi, thanks for the prompt reply. I can now host the SOAP web-service
on Windows. As suggested I made the console app to a ASP.NET web-app.
I got the wsdl but had to tweak the namespace in the AssemblyInfo.cs
file as mentioned in some post.
For now if possible I would really like to stick to either the
ServiceReference approach or the ChannelFactory one that I mentioned
in my earlier comment for the SOAP client/proxy. As later on I would
be writing a complex web-service and handing off the wsdl to other
people so that they can
come with a proxy and they use WCF to generate clients. So basically
looking at interop between ServiceStack SOAP service and WCF SOAP
client.

If I try to consume the hello web-service from a client created using
the ServiceReference approach I get the following exceptions:


Error trying to deserialize requestType: TestWebApp.Hello, xml body:
<Hello xmlns="http://schemas.servicestack.net/types"><Name>Trying
ServiceStack</Name></Hello>

and

The content type text/html; charset=utf-8 of the response message does
not match the content type of the binding (application/soap+xml;
charset=utf-8). If using a custom encoder, be sure that the
IsContentTypeSupported method is implemented properly. The first 1024
bytes of the response were: '<!DOCTYPE html>
<html>
    <head>
        <title>Value cannot be null.<br>Parameter name: httpReq</
title>
        <meta name="viewport" content="width=device-width" />
        <style>
         body {font-family:"Verdana";font-weight:normal;font-size: .
7em;color:black;}
         p {font-family:"Verdana";font-
weight:normal;color:black;margin-top: -5px}
         b {font-family:"Verdana";font-weight:bold;color:black;margin-
top: -5px}
         H1 { font-family:"Verdana";font-weight:normal;font-size:
18pt;color:red }
         H2 { font-family:"Verdana";font-weight:normal;font-size:
14pt;color:maroon }
         pre {font-family:"Consolas","Lucida Console",Monospace;font-
size:11pt;margin:0;padding:0.5em;line-height:14pt}
         .marker {font-weight: bold; color: black;text-decoration:
none;}
         .version {color: gray;}
         .error {margin-bottom: 10px;}
         .expandable { text-decoration:underline; font-weight:bold;
color:navy; cursor:hand; }
         @media screen and (max-width: 639px)'.

Has anybody encountered similar issues?

Thanks for all the help so far.

Regards.

On Apr 17, 10:30 am, Demis Bellot <demis.bel...@gmail.com> wrote:
> All the examples onhttps://github.com/ServiceStack/ServiceStack.Examples/arein C# and
> the Starter Templates show the same app in each of the
> different host configurations:https://github.com/ServiceStack/ServiceStack.Examples/tree/master/src...
>
> the async part means that it can handle multiple request at the same time?
>
> > correct?
>
> No it can already handle multiple requests at the same time. Async means
> its non-blocking i.e. no threads are blocked whilst waiting for an IO
> Response.
>
> Cheers,
>
> On Tue, Apr 17, 2012 at 10:25 AM, Erik van den Berg <ajh...@gmail.com>wrote:
>
>
>
>
>
>
>
> > Woow, it's a bit over my head and would love to see something like this in
> > C#, the async part means that it can handle multiple request at the same
> > time? correct?
>
> > On Tue, Apr 17, 2012 at 3:59 PM, Demis Bellot <demis.bel...@gmail.com>wrote:
>
> >> Is hosting on ASP.NET/IIS <http://asp.net/IIS> the only way?
>
> >> For SOAP Yes, its only supported on ASP.NET Hosts.
> >> However you can easily convert between a HttpListener and ASP.NET host
> >> app as seen at:http://www.servicestack.net/mythz_blog/?p=785
>
> >> How would the service host/work when I copy the binaries on Linux. Would
> >>> I need an equivalent of IIS on Linux like Apache running?
>
> >> For ASP.NET Hosts you would need to configure it to run in
> >> Apache/mod_mono or alternatively using something like Nginx/MonoFastCgi.
>
> >> Note: You only need the WSDL to code-gen your client proxies, you can
> >> still call the SOAP endpoints without code-gen clients (i.e. the
> >> recommended approach) by just using the built-in generic service clients,
> >> e.g:
>
> >>https://github.com/ServiceStack/ServiceStack/blob/master/tests/Servic...
>
> >> You are using SOAP when you HTTP POST a SOAP Envelope request to a SOAP
> >> endpoint which for servicestack is located at /api/soap11/{OperationName}
> >> or /api/soap12/{OperationName}
> >> This is what the generic Soap11ServiceClient/Soap12ServiceClient does for
> >> you.
>
> >> Cheers,
>
> ...
>
> read more »

Demis Bellot

unread,
Apr 17, 2012, 5:39:04 PM4/17/12
to servic...@googlegroups.com
You'll have to compare what the Generated SOAP Clients send vs what the Generic ServiceClients send - which will be what ServiceStack expects.
If you inspect the WcfServiceClient source code (i.e. the Soap Clients base class) you'll notice it's just a wrapper around WCF's GenericProxy:

There are some tips you should stick to like making sure all your XML Namespaces are the same, not returning more than 1 property/result (which otherwise uglifies the code-gen'ed proxies WCF ServiceReference generates), keep the {OperationType} / {OperationType}Response DTO naming conventions, etc.

Supporting the output of WCF's (or someone else's) code-gen proxy is not something I wish to spend time on supporting since as I mentioned earlier using the generic ServiceClients + Server DTOs is the recommended approach.

Behind the scenes, all the XSDs do are generate uglier versions of the server DTOs on the client (which can also be used in the generic ServiceClients). And all the WSDLs does is code-gen a tightly-coupled endpoint-specific RPC boilerplate around all your Web Service Operations which is a poorer, less maintainable, versionable substitute then using the Generic Service Clients.

For the best chance of getting help from others here, submit a stand-alone failing integration tests that makes it easier for others to reproduce.

- Demis

devqu...@yahoo.com

unread,
Apr 18, 2012, 10:14:44 AM4/18/12
to ServiceStack .NET Open Source REST Web Services Framework
Thanks Demis for your reply. Apparently I had downloaded the examples
zip v3.23 and was using the binaries from the lib folder. I started
browsing the code in the repository and saw many releases after that.
I now downloaded v3.63, with that 'Add service reference' approach
works fine. I will keep this thread updated with my experience with
SOAP on ServiceStack. Thanks again for all the help.

On Apr 17, 5:39 pm, Demis Bellot <demis.bel...@gmail.com> wrote:
> You'll have to compare what the Generated SOAP Clients send vs what the
> Generic ServiceClients send - which will be what ServiceStack expects.
> If you inspect the WcfServiceClient source code (i.e. the Soap Clients base
> class) you'll notice it's just a wrapper around WCF's GenericProxy:https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceS...
>
> There are some tips you should stick to like making sure all your XML
> Namespaces are the same, not returning more than 1 property/result (which
> otherwise uglifies the code-gen'ed proxies WCF ServiceReference generates),
> keep the {OperationType} / {OperationType}Response DTO naming conventions,
> etc.
>
> Supporting the output of WCF's (or someone else's) code-gen proxy is not
> something I wish to spend time on supporting since as I mentioned
> earlier using the generic ServiceClients + Server DTOs is the recommended
> approach.
>
> Behind the scenes, all the XSDs do are generate uglier versions of the
> server DTOs on the client (which can also be used in the generic
> ServiceClients). And all the WSDLs does is code-gen a tightly-coupled
> endpoint-specific RPC boilerplate around all your Web Service Operations
> which is a poorer, less maintainable, versionable substitute then using the
> Generic Service Clients.
>
> For the best chance of getting help from others here, submit a stand-alone
> failing integration tests that makes it easier for others to reproduce.
>
> - Demis
>
> On Tue, Apr 17, 2012 at 4:35 PM, devquer...@yahoo.com
> <devquer...@yahoo.com>wrote:
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages