namespace dilemma in generating WCF proxies

3.1k views Asked by At

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.

1

There are 1 answers

6
Dmitry Harnitski On

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:

C:\Windows\system32>svcutil /directory:D:\prog\myfolder /r:"D:\prog\SampleWcf\Server\bin\Debug\Contract.dll"  http://localhost:8080/Service/mex 

One difference from your code is that I used metadata instead of wsdl.

You have two options:

  1. Generate proxies in Visual Studio.
  2. 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