I have several message contracts that use an external library to standardize a particular functionality between several services. Their code looks somewhat like this...
using System.ServiceModel;
using Query.Search;
[MessageContract(WrapperName = "MyMessageContract")]
public partial class MyMessageContract
{
[MessageBodyMember(Name = "Search")]
public SearchTerms Search { get; set; }
}
The SearchTerms class is in the Query.Search DLL and looks like so...
public class SearchTerms : List<SearchTerm> { }
... with the SearchTerm class also in the same DLL. It works just fine in the service and knows that I'm addressing the Query.Search classes, but when I generate the proxies, these classes are reassigned to the wrong namespace and make it very difficult to build a service adapter in the UI. I'm using svcutil with the following arguments...
/t:code /mc /n:*,MyProject.UI.Proxies /ct:System.Collections.Generic.List`1 /l:cs
/o:WSProxies.cs /config:output.config http://localhost:49207/Service1.svc?wsdl
http://localhost:49207/Service2.svc?wsdl http://localhost:49207/Service3.svc?wsdl
Now, I understand that the namespace argument as it's defined here is basically assigning all my proxy namespaces to MyProject.UI.Proxies and if I remove it, the namespaces for my Query.Search class are set correctly. However, this means that all the other proxies now fall under the default "MyService.DataContracts" namespace in which they're defined. So I tried using...
/n:MyService.DataContracts,MyProject.UI.Proxies
... but had no luck as the output reverts to "MyService.DataContracts" after it's generated. What I'd like to be able to do is for my proxies to have the UI namespace of "MyProject.UI.Proxies" while maintaining the namespace for the SearchTerms class as "Query.Search" without manually modifying the output file so a new run of svcutil doesn't wipe out the manual changes. Is this possible and am I just using the /namespace argument wrong, or will I have to manually modify the output file every time I generate proxies?
EDIT: After a fruitless day of trying to get this working, I simply created a workaround, creating a set of similar classes in the services and translating them to the Query.Search ones. Would still be interested to know if what I wanted can be done but form what I've gathered, using these classes in a message contract sort of dooms it to be listed under the same namespace as the MC.
You should tell
svcutil
to reuse your classes instead of fighting with proxy namespaces. This is achievable using/reference
parameter.It also will be good idea to move all such classes to separate assembly. Otherwise you will have direct reference between WCF server and client what is not good architecturally.
Check this link for sample:
http://blogs.msdn.com/b/youssefm/archive/2009/10/09/reusing-types-in-referenced-assemblies-with-svcutil-s-r-switch.aspx
You also can do the same task in Visual Studio. See my answer here:
How to use a custom type object at the client
Update:
I did some investigation. You are right SVCUtil does not generate proxy classes if you references assembly that contains all interfaces and data contracts.
That behavior is different from Visual Studio. Visual Studio seems to not use SVCUtil work with WCF directly.
This is command line I tried:
One difference from your code is that I used metadata instead of wsdl.
You have two options:
Work with Service without profies using
ChannelFactory
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://localhost/MathService/Ep1");
ChannelFactory myChannelFactory = new ChannelFactory(myBinding, myEndpoint);
IMath wcfClient1 = myChannelFactory.CreateChannel();
http://msdn.microsoft.com/en-us/library/ms734681.aspx