I just updated my references to the new ServiceStack from nuget (from 3.9.11 to version 3.9.56) and I could not get my soap clients to work. So I decided to try once again the Hello World solution provided on [github] (https://github.com/ServiceStack/ServiceStack.Examples/tree/master/src/ServiceStack.Hello) which by the way is using an older version (3.9.32).
I added the [DataContract]
attributes on the Hello
and HelloResponse
classes and then I tried to build a C# console client by adding a service reference to my localhost soap12 endpoint (using the Add Service Reference on VS2010, also tried 2012 and 2013). Unfortunately while I do get the OneWayClient
and the SyncReplyClient
I do not get any of my DTOs generated. Why is that? I tried to build my code with an older version of ServiceStack (using the IService<T>
and the Execute
method and everything worked fine! Are there any breaking changes that I am not aware of?
P.S. I tried also to recompile the whole ServiceStack.Examples project against the nuget libraries and it failed too. I could not even generate the proxy. Please do not try to convince me to use a share assembly for my DTOs as this defeats the purpose of having a language agnostic web service!
I have finally solved the issue so I am going to post the answer here. ServiceStack is not as broken as it seems although all the examples on the github repo need an update to work with the latest version. So to the point: if you want your classes to correctly produce proxy classes you have to decorate them all not only with the [DataContract]
attribute on the class level but also with the [DataMember]
on the property level i.e.
[DataContract]
class User
{
[DataMember]
public String Name { get; set; }
}
Of course you also need to either specify the namespace on the [DataContract]
attribute (for Mono compatibility) or you will have to add a few lines on the AssemblyInfo.cs as described here.
Be warned though! All your DTOs including request types and response types should be on the same namespace! Also if you define only first level classes as request types (like the User example I used) then you will not get a proxy class! Instead all the public members will become method parameters. If you had though, by composition, another public member within User class i.e.
[DataContract]
class User
{
[DataMember]
public String Name { get; set; }
[DataMember]
public MyClass MyMember { get; set; }
}
then you would get your proxies for the MyClass though not for User. As for response types better read the ServiceStack wiki on SOAP limitations.
Last note: I usually have strong opinions only about flexibility, simplicity, finding alternatives and making things work. I find pointless the discussions that try to support a language over another, an architecture over another, a buzzword/niche technology over a standard approach, using tools that make life easier over hardcoding everything. So I see as such the discussion on the comments above and I wish to continue no more.
I am just glad that a great tool like ServiceStack continues to provide what most users use it for: A variety of alternatives.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments