I have a C# WCF service and I need to reference another web service. The old service is written in Visual Basic and is not WCF.
The former is supposed to deprecate the latter, but there are some methods in the old service which are complex. Consequently, I would like to call the methods in the old service from the new service.
To avoid naming confusion I want to encapsulate the wrapper for the old services in a separate project, which is referenced from the new service. However, when I tried calling the wrapper from the new services project, the new service threw an InvalidSoapOperation. This exception is not thrown when I call the old services from the wrapper project itself.
Normally, I'd copy and paste the bindings for the old service from the wrapper project to the new project, but because of the similarity of the contracts, I am hesistant to do that.
Is there a way to "indirectly" reference the old service through the wrapper project, so that the new service project is not directly coupled the old service?
EDIT: The stack trace is as follows:
System.InvalidOperationException was unhandled by user code
HResult=-2146233079
Message=Could not find default endpoint element that references contract 'OldService.OldServiceSoap' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
Source=System.ServiceModel
StackTrace:
at System.ServiceModel.Description.ConfigLoader.LoadChannelBehaviors(ServiceEndpoint serviceEndpoint, String configurationName)
at System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName, Configuration configuration)
at System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName)
at System.ServiceModel.ChannelFactory.InitializeEndpoint(String configurationName, EndpointAddress address)
at System.ServiceModel.ChannelFactory`1..ctor(String endpointConfigurationName, EndpointAddress remoteAddress)
at System.ServiceModel.ConfigurationEndpointTrait`1.CreateSimplexFactory()
at System.ServiceModel.ConfigurationEndpointTrait`1.CreateChannelFactory()
at System.ServiceModel.ClientBase`1.CreateChannelFactoryRef(EndpointTrait`1 endpointTrait)
at System.ServiceModel.ClientBase`1.InitializeChannelFactoryRef()
at System.ServiceModel.ClientBase`1..ctor()
at OldServiceWrapper.OldService.OldServiceClient..ctor() in C:...\MyProject\Service References\TheOldService\Reference.cs:line 21614
The App.Config in the Wrapper Project:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="OldServiceSoap" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/OldService/OldService.asmx"
binding="basicHttpBinding" bindingConfiguration="LogOrderSoap"
contract="OldService.OldServiceSoap" name="OldServiceSoap"/>
</client>
</system.serviceModel>
The solution is to copy and paste the binding and client information in the referenced project to that of the wrapper project.
As stated in C# DLL config file:
Whereas there is rarely a need to track settings separately for different copies of an app within one user profile, it's very unlikely that you would want all of the different usages of a DLL to share configuration with each other. For this reason, when you retrieve a Configuration object using the "normal" method, the object you get back is tied to the configuration of the App Domain you are executing in, rather than the particular assembly.
Or as Sam Holder put in Reference Web.Config file from another project in same solution C#:
class libraries do not have their own configuration. They use the configuration of which ever executable they are being used in.
In C#, the standard practice is that configuration should belong to the application, not the referenced DLL. Therefore, it makes sense to copy and paste the app.config information to the calling project. This does not require you to reference the old web service from the calling project directly, as I was worried that it would.