Search code examples
c#wcfself-hosting

There was no endpoint listening at <url> that could accept the message


I'm trying to create a self-hosted WCF service to facilitate communication between two MS-Office addins on the same machine. The idea is that they'll pass document meta-data between them.

I keep running into the error in the title.

The contract / implementation:

namespace test.intermediaryservicehost
{
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IIntermediaryObject
    {
        [OperationContract]
        bool GetIsWorking();
        [OperationContract]
        void SetIsWorking(bool working);


        [OperationContract]
        Dictionary<string, string> GetDocInfo();
        [OperationContract]
        void SetDocInfo(Dictionary<string, string> doc_info);

        [OperationContract]
        Dictionary<string, string> GetIndices();
        [OperationContract]
        void SetIndices(Dictionary<string, string> index_dict);

    }
}

namespace test.intermediaryservicehost
{

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class IntermediaryObject : IIntermediaryObject
    {
        private bool isWorking;

        private string Doc_Location;
        private string Doc_Name;

        private string Template_CorrespondenceType;
        private string Template_Reference;
        private string Template_Type; // "I" == Inbound, "O" == Outbound
        private string Template_Name;


        public bool GetIsWorking()
        {
            return this.isWorking;
        }
        public void SetIsWorking(bool working)
        {
            this.isWorking = working;
        }

        public Dictionary<string, string> GetDocInfo()
        {            
            Dictionary<string, string> doc_info = new Dictionary<string, string>();
            doc_info.Add("Doc_Location", this.Doc_Location);
            doc_info.Add("Doc_Name", this.Doc_Name);
            return doc_info;
        }
        public void SetDocInfo(Dictionary<string, string> doc_info)
        {
            this.Doc_Location = doc_info["Doc_Location"];
            this.Doc_Name = doc_info["Doc_Name"];         
        }

        public Dictionary<string, string> GetIndices()
        {
            Dictionary<string, string> indices = new Dictionary<string, string>();
            indices.Add("Template_CorrespondenceType", this.Template_CorrespondenceType);
            indices.Add("Template_Reference", this.Template_Reference);
            indices.Add("Template_Type", this.Template_Type);
            indices.Add("Template_Name", this.Template_Name);
            return indices;            
        }

        public void SetIndices(Dictionary<string, string> indices)
        {
            this.Template_CorrespondenceType = indices["Template_CorrespondenceType"];
            this.Template_Reference = indices["Template_Reference"];
            this.Template_Type = indices["Template_Type"];
            this.Template_Name = indices["Template_Name"];            
        }
    }
} 

And here is the code for the service host (a windows form in the same project/namespace):

    private void Form1_Load(object sender, EventArgs e)
    {
        this.Visible = false;
        string svcLocation = "";
        try
        {
            svcLocation = ConfigurationManager.AppSettings["serviceUrl"] == null ? "http://localhost:1112/IntermediaryObject" : ConfigurationManager.AppSettings["serviceUrl"].ToString();
            SvcHost = new ServiceHost(typeof(test.intermediaryservicehost.IntermediaryObject), new Uri(svcLocation));
            SvcHost.Open();
        }
        catch (Exception ex)
        {
        }
    }

I'm using the following configuration in the host's app.config:

  <appSettings>
    <add key="serviceUrl" value="http://localhost:1112/IntermediaryObject"/>
  </appSettings>  

<bindings>
  <wsDualHttpBinding>
    <binding name="WsHttpBinding_IIntermediaryObject" closeTimeout="00:01:00"/>
  </wsDualHttpBinding>
</bindings>

<services>
  <service name="test.intermediaryservicehost.IntermediaryObject" behaviorConfiguration="metaDataBehavior">
    <endpoint address="http://localhost:1112/IntermediaryObject"
              binding="wsDualHttpBinding"
              bindingConfiguration="WsHttpBinding_IIntermediaryObject"
              contract="test.intermediaryservicehost.IIntermediaryObject"/>
  </service>
</services>

<behaviors>
  <serviceBehaviors>
    <behavior name="metaDataBehavior">
      <serviceMetadata httpGetEnabled="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

And the following on the client side config:

  <system.serviceModel>
<bindings>
  <wsDualHttpBinding>
    <binding name="WSDualHttpBinding_IIntermediaryObject" />
  </wsDualHttpBinding>
</bindings>

<client>
  <endpoint     address="http://localhost:1112/IntermediaryObject"
                binding="wsDualHttpBinding" 
                bindingConfiguration="WSDualHttpBinding_IIntermediaryObject"
                contract="IIntermediaryObject" 
                name="WSDualHttpBinding_IIntermediaryObject">        
  </endpoint>
</client>

<diagnostics>
  <messageLogging   logMessagesAtTransportLevel="true"
                    logMessagesAtServiceLevel="false"
                    logMalformedMessages="true"
                    logEntireMessage="true"
                    maxSizeOfMessageToLog="65535000"
                    maxMessagesToLog="1000"/>
</diagnostics>

A couple of other facts about the service: It uses SessionMode.Required on the ServiceContract, so state will be stored. The implementation InstanceContextMode.Single in the ServiceBehavior attribute

Trace info:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
    <EventID>131075</EventID>
    <Type>3</Type>
    <SubType Name="Error">0</SubType>
    <Level>2</Level>
    <TimeCreated SystemTime="2018-06-18T11:01:42.4511686Z" />
    <Source Name="System.ServiceModel" />
    <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
    <Execution ProcessName="OUTLOOK" ProcessID="1724" ThreadID="1" />
    <Channel />
    <Computer>[<COMP-NAME></Computer>
</System>
<ApplicationData>
    <TraceData>
        <DataItem>
            <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
                <TraceIdentifier>http://msdn.microsoft.com/en-IE/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
                <Description>Throwing an exception.</Description>
                <AppDomain>test.outlookaddin.vsto|vstolocal</AppDomain>
                <Exception>
                    <ExceptionType>System.ServiceModel.EndpointNotFoundException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
                    <Message>There was no endpoint listening at http://localhost:1112/IntermediaryObject that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.</Message>
                    <StackTrace>   at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()
                                   at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
                                   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout)
                                   at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
                                   at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
                                   at System.ServiceModel.Security.SspiNegotiationTokenProvider.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Security.CommunicationObjectSecurityTokenProvider.Open(TimeSpan timeout)
                                   at System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
                                   at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
                                   at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
                                   at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.SyncWaiter.TryGetChannel()
                                   at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.SyncWaiter.TryWait(TChannel&amp;amp; channel)
                                   at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.TryGetChannel(Boolean canGetChannel, Boolean canCauseFault, TimeSpan timeout, MaskingMode maskingMode, TChannel&amp;amp; channel)
                                   at System.ServiceModel.Channels.ReliableChannelBinder`1.Send(Message message, TimeSpan timeout, MaskingMode maskingMode)
                                   at System.ServiceModel.Channels.SendReceiveReliableRequestor.OnRequest(Message request, TimeSpan timeout, Boolean last)
                                   at System.ServiceModel.Channels.ReliableRequestor.Request(TimeSpan timeout)
                                   at System.ServiceModel.Channels.ClientReliableSession.Open(TimeSpan timeout)
                                   at System.ServiceModel.Channels.ClientReliableDuplexSessionChannel.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
                                   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
                                   at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
                                   at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
                                   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
                                   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
                                   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
                                   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp;amp; msgData, Int32 type)
                                   at IIntermediaryObject.SetIndices(Dictionary`2 index_dict)
                                   at IntermediaryObjectClient.SetIndices(Dictionary`2 index_dict)
                                   at test.pluginforms.frmTemplateData.CallWord()
                                   at test.pluginforms.frmTemplateData.btnGenerate_Click(Object sender, EventArgs e)
                                   at System.Windows.Forms.Control.OnClick(EventArgs e)
                                   at System.Windows.Forms.Button.OnClick(EventArgs e)
                                   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
                                   at System.Windows.Forms.Control.WmMouseUp(Message&amp;amp; m, MouseButtons button, Int32 clicks)
                                   at System.Windows.Forms.Control.WndProc(Message&amp;amp; m)
                                   at System.Windows.Forms.ButtonBase.WndProc(Message&amp;amp; m)
                                   at System.Windows.Forms.Button.WndProc(Message&amp;amp; m)
                                   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp;amp; m)
                                   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;amp; m)
                                   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
                    </StackTrace>
                    <ExceptionString>
                                    System.ServiceModel.EndpointNotFoundException: There was no endpoint listening at http://localhost:1112/IntermediaryObject that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details. ---&amp;gt; System.Net.WebException: Unable to connect to the remote server ---&amp;gt; System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:1112
                                        at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
                                        at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket&amp;amp; socket, IPAddress&amp;amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp;amp; exception)
                                    --- End of inner exception stack trace ---
                                    at System.Net.HttpWebRequest.GetRequestStream(TransportContext&amp;amp; context)
                                    at System.Net.HttpWebRequest.GetRequestStream()
                                    at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()
                                    --- End of inner exception stack trace ---
                    </ExceptionString>
                    <InnerException>
                        <ExceptionType>System.Net.WebException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
                        <Message>Unable to connect to the remote server</Message>
                        <StackTrace>    at System.Net.HttpWebRequest.GetRequestStream(TransportContext&amp;amp; context)
                                        at System.Net.HttpWebRequest.GetRequestStream()
                                        at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()
                        </StackTrace>
                        <ExceptionString>
                                        System.Net.WebException: Unable to connect to the remote server ---&amp;gt; System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:1112
                                       at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
                                       at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket&amp;amp; socket, IPAddress&amp;amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp;amp; exception)
                                       --- End of inner exception stack trace ---
                                       at System.Net.HttpWebRequest.GetRequestStream(TransportContext&amp;amp; context)
                                       at System.Net.HttpWebRequest.GetRequestStream()
                                       at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()
                        </ExceptionString>
                        <InnerException>
                            <ExceptionType>System.Net.Sockets.SocketException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
                            <Message>No connection could be made because the target machine actively refused it 127.0.0.1:1112</Message>
                            <StackTrace>   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
                                            at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket&amp;amp; socket, IPAddress&amp;amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp;amp; exception)</StackTrace>
                            <ExceptionString>System.Net.Sockets.SocketException (0x80004005): No connection could be made because the target machine actively refused it 127.0.0.1:1112
                                               at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
                                               at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket&amp;amp; socket, IPAddress&amp;amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp;amp; exception)
                            </ExceptionString>
                            <NativeErrorCode>274D</NativeErrorCode>
                        </InnerException>
                    </InnerException>
                </Exception>
            </TraceRecord>
        </DataItem>
    </TraceData>
</ApplicationData>


Solution

  • The issue ended up being the binding. wsDualHttpBinding requires endpoints listening at the request and response ends. My client apps (both office addins) were not listening at any url and hence my error. Suspect this is the conclusion that CodeCaster was trying to drag me, kicking and screaming towards!

    I switched to a more appropriate binding for my application; netNamedPipeBinding.

    My new host config:

      <system.serviceModel>    
        <bindings>
          <netNamedPipeBinding>
            <binding name="NetNamedPipeBinding_IIntermediaryObject" closeTimeout="00:01:00"/>
          </netNamedPipeBinding>
        </bindings>    
        <services>
          <service name="test.intermediaryservicehost.IntermediaryObject" >
            <endpoint address="net.pipe://localhost/IntermediaryObject"
                  binding="netNamedPipeBinding"
                  bindingConfiguration="NetNamedPipeBinding_IIntermediaryObject"
                  contract="test.intermediaryservicehost.IIntermediaryObject"/>
            <endpoint binding="mexNamedPipeBinding" name="mex" address="mex" contract="IMetadataExchange"/>
            </service>
       </services>    
       <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata />
            </behavior>
          </serviceBehaviors>
       </behaviors>   
    

    And a client config sample:

    <system.serviceModel>
        <bindings>
          <netNamedPipeBinding>
            <binding name="NetNamedPipeBinding_IIntermediaryObject" />
          </netNamedPipeBinding>
        </bindings>
        <client>
          <endpoint address="net.pipe://localhost/IntermediaryObject" binding="netNamedPipeBinding"
          bindingConfiguration="NetNamedPipeBinding_IIntermediaryObject"
          contract="IIntermediaryObject" name="NetNamedPipeBinding_IIntermediaryObject">       
          </endpoint>
        </client>    
        <diagnostics>
            <!-- Unrelated tracing info, removed for brevity -->
        </diagnostics>
    </system.serviceModel>
    

    This answer helped me generate the required client configuration/proxy class for the netNamedPipeBinding