I have a WCF service let's call it UserService
. The UserService
has a reference to a class library. Let's call it DoWork.dll
. The DoWork.dll
has a WCF service reference to a different service we'll call CompanyService
.
Now, when I first tried calling the UserService
I would get an endpoint not configured error message. After reading around the web I've found that I need to add the CompanyService
bindings and client information into the UserService
's web.config
under the <system.serviceModel>
node.
Here it is:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IComapnyService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint name="BasicHttpBinding_ICompanyService"
address="http://it-dev.company.local:81/Project/Copmpany/CompanyService.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IComapnyService"
contract="CompanyService.ICompanyService" />
</client>
The problem I have is the contract="CompanyService.ICompanyService"
shows me the error:
The 'contract' attribute is invalid - The value 'CompanyService.ICompanyService' is invalid according to its datatype 'clientContractType' - The Enumeration constraint failed.
Now, if I add the CompanyService
reference directly to the UserService
WCF project, the error goes away (obviously). However, I shouldn't have to do this. I have tried fully qualifying the namespace the ICompanyService
contract is in and that doesn't work either. I have deleted the .suo file and rebuild the project and that doesn't work either (suggested elsewhere on the web). Also, if I type contract=
, I get the drop down list but CompanyService.ICompanyService
is nowhere to be found (only when I reference the service directly in the UserService
project).
I have tried configuring it using Tools > WCF Service Configuration Editor
and that does not help.
I should note that everything seems to work fine, but I don't like the fact that intellisense is giving me the blue squiggly underline and that error message. I have a feeling I need something else in the web.config
to get this to work since the UserService
references the DoWork.dll
, which in turn references the CompanyService
whose contract I cannot see properly.
Any suggestions are much appreciated. Thanks in advance.
You're right - you should not have to do this.
The architecture of having a DLL (DoWork.dll) with a "service reference" (ComanyService) is bad. Unless the DLL has hard-coded the client endpoint (in code) to call the CompanyService for you, then anyone using the DLL will have to try and figure out how to configure the client endpoint for a service they don't know about. Which is what your running into.
The reason this works when you add a service reference directly from your UserService is that when you do this, you get a copy of the ServiceContract from the CompanyService metadata. To prove this, look in the Reference.cs file that get's generated, search for CompanyService and you will find it has the [ServiceContract] attribute, identifying it as a WCF service. Furthermore, you will see the [OperationContract] attributes for the methods, plus any [DataContracts] the service my also exchange. In other words, all these "types" got imported into your project and when you compile, WCF is now able to find these types when instantiating the client endpoint.
If CompanyService is one of your services, then consider extracting out the ServiceContract definition (interface) into a separate DLL. Then, you can reference those types as "assembly references" from the service (CompanyService) and any client applications, such as UserService. At least that way you're not having to add a service reference. But, you still have to populate the .... section in your application for a service you technically may not know the details of. Not the best approach.
A better approach is to move the service dependency out of the DoWork.dll. You could do this by just moving the logic into the UserService implementation.
Or, if you need to keep DoWork.dll independent, then consider wrapping DoWork with it's on WCF Service, which takes a dependency on the CompanyService. Then, from UserService, add a service reference to the new DoWork service. This is more in keeping with the tenants of SOA and will allow your services to evolve independently.