Search code examples
c#visual-studiowcfdllself-hosting

Self host WCF Web Service in Managed Application change the definition of the Service


I am struggling try to figure out the problem, but I can't, and I can't find proper solution on google.

I have a WCF Web Service in a Class Library project in Visual Studio, with the interface IWebService , the implementazion WebService and the config with the file App.config that exposed two method Instruction(string) and Update(), the service take and instruction, save it in a list FIFO, return a response and then I can retrieve the first element of the list with the second method.

IWebService.cs

 [ServiceContract(Namespace = "SMS_Application")]
  [XmlSerializerFormat]
  public interface IWebService
  {
    [OperationContract(Action = "Instruction", Name = "Instruction", ReplyAction = "InstructionResponse")]
    string[] Instruction(string Username, string Password, string Command);

    [OperationContract(Action = "GetUpdate", Name = "GetUpdate")]
    string GetUpdate(string Username, string Password);
}

App.config

<?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="Callback">
        <endpoint address="" binding="basicHttpBinding" name="Callback"
          contract="SLWebServiceServer.IWebService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/SLWebServiceServer/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          ...
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

If I create a console app with self host (using ServiceHost) inside the same solution (so two projects, one solution) in visual studio and I start the console app, all works as expected. The problem is that I have a big application, with multiple DLL in multiple solution, what I want is to add the reference to the WebService in one DLL and start self host. But if I add the reference to the WebService and start the service, the definition cahnge and also the URL, but if I add the WebService project to the current solution all return to works as expected.

I can't find the problem, I thing that is something to do with the App.config files but I can't find what.

This is how I created the self host:

Uri baseAddress = new Uri(URL);
         string URL = "http://localhost:8733/SLWebServiceServer/";
        // Create a ServiceHost instance.
        ServiceHost _host = new ServiceHost(typeof(WebService), baseAddress);
        try {
          // Add a service endpoint.
          var binding = new WSHttpBinding();
          _host.AddServiceEndpoint(typeof(IWebService), binding, "Application");
          var behavior = _host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
          behavior.InstanceContextMode = InstanceContextMode.Single;
          // Enable metadata exchange.
          ServiceMetadataBehavior smb = new ServiceMetadataBehavior {
            HttpGetEnabled = true
          };
          _host.Description.Behaviors.Add(smb);
          // Start the service.
          _host.Open();
        }
        catch (CommunicationException ce) {
          _host.Abort();
        }

This is the WSDL file that it creates with the solution with two project

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:i0="http://tempuri.org/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="SMS_Application" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="WCallback" targetNamespace="SMS_Application">
<wsdl:import namespace="http://tempuri.org/" location="http://192.168.8.101:8733/SLWebServiceServer/?wsdl=wsdl0"/>
<wsdl:types>
<xsd:schema targetNamespace="SMS_Application/Imports">
<xsd:import schemaLocation="http://192.168.8.101:8733/SLWebServiceServer/?xsd=xsd0" namespace="SMS_Application"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IWebService_Instruction_InputMessage">
<wsdl:part name="parameters" element="tns:Instruction"/>
</wsdl:message>
<wsdl:message name="IWebService_Instruction_OutputMessage">
<wsdl:part name="parameters" element="tns:InstructionResponse"/>
</wsdl:message>
<wsdl:message name="IWebService_GetUpdate_InputMessage">
<wsdl:part name="parameters" element="tns:GetUpdate"/>
</wsdl:message>
<wsdl:message name="IWebService_GetUpdate_OutputMessage">
<wsdl:part name="parameters" element="tns:GetUpdateResponse"/>
</wsdl:message>
<wsdl:portType name="IWebService">
<wsdl:operation name="Instruction">
<wsdl:input wsaw:Action="Instruction" message="tns:IWebService_Instruction_InputMessage"/>
<wsdl:output wsaw:Action="InstructionResponse" message="tns:IWebService_Instruction_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="GetUpdate">
<wsdl:input wsaw:Action="GetUpdate" message="tns:IWebService_GetUpdate_InputMessage"/>
<wsdl:output wsaw:Action="SMS_Application/IWebService/GetUpdateResponse" message="tns:IWebService_GetUpdate_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:service name="Callback">
<wsdl:port name="Callback" binding="i0:Callback">
<soap:address location="http://192.168.8.101:8733/SLWebServiceServer/"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

and this with the only one project and the WebService only as external reference

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="SMS_Application" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:i0="http://tempuri.org/" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" name="Callback" targetNamespace="SMS_Application">
<wsdl:import namespace="http://tempuri.org/" location="http://192.168.8.101:8733/SLWebServiceServer/?wsdl=wsdl0"/>
<wsdl:types>
<xsd:schema targetNamespace="SMS_Application/Imports">
<xsd:import schemaLocation="http://192.168.8.101:8733/SLWebServiceServer/?xsd=xsd0" namespace="SMS_Application"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IWebService_Instruction_InputMessage">
<wsdl:part name="parameters" element="tns:Instruction"/>
</wsdl:message>
<wsdl:message name="IWebService_Instruction_OutputMessage">
<wsdl:part name="parameters" element="tns:InstructionResponse"/>
</wsdl:message>
<wsdl:message name="IWebService_GetUpdate_InputMessage">
<wsdl:part name="parameters" element="tns:GetUpdate"/>
</wsdl:message>
<wsdl:message name="IWebService_GetUpdate_OutputMessage">
<wsdl:part name="parameters" element="tns:GetUpdateResponse"/>
</wsdl:message>
<wsdl:portType name="IWebService">
<wsdl:operation name="Instruction">
<wsdl:input wsaw:Action="Instruction" message="tns:IWebService_Instruction_InputMessage"/>
<wsdl:output wsaw:Action="InstructionResponse" message="tns:IWebService_Instruction_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="GetUpdate">
<wsdl:input wsaw:Action="GetUpdate" message="tns:IWebService_GetUpdate_InputMessage"/>
<wsdl:output wsaw:Action="SMS_Application/IWebService/GetUpdateResponse" message="tns:IWebService_GetUpdate_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:service name="Callback">
<wsdl:port name="WSHttpBinding_IWebService" binding="i0:WSHttpBinding_IWebService">
<soap12:address location="http://192.168.8.101:8733/SLWebServiceServer/Application"/>
<wsa10:EndpointReference>
<wsa10:Address>http://192.168.8.101:8733/SLWebServiceServer/Application</wsa10:Address>
<Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
<Upn>[email protected]</Upn>
</Identity>
</wsa10:EndpointReference>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

If need more infos I can add them.


Solution

  • I see that you have configured endpoint related information in the configuration file, so we don’t need to use code to configure endpoint related information in ServiceHost, we only need to create a servicehost instance and start it:

    ServiceHost selfHost = new ServiceHost(typeof(Service1));
                selfHost.Open();
                Console.WriteLine("Service Open");
                Console.ReadLine();
    

    This is my file directory:

    enter image description here

    I referenced WcfserviceLibrary4 in ConsoleAPP1.

    enter image description here

    The most important point is that we need to copy the app.config in WcfserviceLibrary4 to ConsoleAPP1.

    Feel free to let me know if the problem persists.