Search code examples
c#.netwcf

My wcf client side shows exception but WcfTestClient Tool works fine


I have coded a WCF server side with netTcpBinding. Then I coded a client side. But it shows exception while excute "var sc = new CommondServiceClient();" at runtime. What should I do?

Below is the exception message:

System.InvalidOperationException HResult=0x80131509 Message=Could not find default endpoint element that references contract 'ICommondService' 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: ......

I have tried something:

  1. I can consume the services with WcfTestClient.
  2. The service reference is added by visual studio "add service reference...". I guess I get the service mex data. But I meet runtime exception like above
  3. I also tried generate code with svcutil tool, but it still not work

Here is the wcf config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service name="ServiceContractor.CommondService">
        <endpoint address="" binding="netTcpBinding" contract="ServiceContractor.ICommondService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
       </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="False" httpsGetEnabled="False"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

It's a self host wcf service:

            var baseAddress = new Uri($"net.tcp://localhost:{PORT}/Company/service");
            _host = new ServiceHost(typeof(CommondService), baseAddress);
            try
            {
                var smb = _host.Description.Behaviors.Find<ServiceMetadataBehavior>();
                if (smb == null) _host.Description.Behaviors.Add(new ServiceMetadataBehavior());
                _host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
                _host.AddServiceEndpoint(typeof(ICommondService), new NetTcpBinding(), "");

                _host.Open();
            }
            catch (CommunicationException ce)
            {
                _host.Abort();
            }

I have no idea what is wrong. What document I should ask for? Can you help me?


Solution

  • But I have another question now. Is it possible to get rid of the configuration. So that the application just needs the DLL and knows nothing about the WCF service.

    Generally speaking, there are two ways to call the WCF service (Soap service) in the web application.

    • Generate the client proxy class by adding service reference, this way commonly need to configure the service settings in the configuration file(web.config), most of service information need to be called are stored in the configuration file. For class library project, we have to migrate the configuration to the configuration file of the actual project.
      https://learn.microsoft.com/en-us/dotnet/framework/wcf/accessing-services-using-a-wcf-client
    • Use the ChannelFactory to create the communication channel, we set up the service configurations programmatically. From your description, this way to call the web service might be the appropriate solution. Customize the service configuration programmatically in the code. One thing must be noted that all the service configuration is hard-coded, such as binding type and service endpoint information. You could refer to the following documents.

    https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-channelfactory Feel free to let me know if there is anything I can help with.