我尝试创建自托管WCF服务,以促进同一台计算机上两个MS-Office插件之间的通信。他们的想法是,他们会在他们之间传递文档元数据。
我一直遇到标题中的错误。
合同/实施:
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"];
}
}
}
这是服务主机的代码(同一项目/命名空间中的窗体):
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)
{
}
}
我在主机的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>
以下是客户端配置:
<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>
有关该服务的其他几个事实: 它在ServiceContract上使用SessionMode.Required,因此将存储状态。 ServiceBehavior属性中的实现InstanceContextMode.Single
<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; channel)
at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.TryGetChannel(Boolean canGetChannel, Boolean canCauseFault, TimeSpan timeout, MaskingMode maskingMode, TChannel&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; 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; m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message&amp; m)
at System.Windows.Forms.ButtonBase.WndProc(Message&amp; m)
at System.Windows.Forms.Button.WndProc(Message&amp; m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&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. ---&gt; System.Net.WebException: Unable to connect to the remote server ---&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; socket, IPAddress&amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp; exception)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetRequestStream(TransportContext&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; 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 ---&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; socket, IPAddress&amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp; exception)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetRequestStream(TransportContext&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; socket, IPAddress&amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&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; socket, IPAddress&amp; address, ConnectSocketState state, IAsyncResult asyncResult, Exception&amp; exception)
</ExceptionString>
<NativeErrorCode>274D</NativeErrorCode>
</InnerException>
</InnerException>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
答案 0 :(得分:0)
这个问题最终成为了约束力。 wsDualHttpBinding要求端点在请求和响应结束时进行侦听。我的客户端应用程序(两个办公室插件)都没有收听任何网址,因此我的错误。怀疑这是CodeCaster试图拖我,踢和尖叫的结论!
我为我的应用程序切换到更合适的绑定; netNamedPipeBinding。
我的新主机配置:
<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>
客户端配置示例:
<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帮助我为netNamedPipeBinding生成所需的客户端配置/代理类