WCF 服务,在 WCF Svc 主机中工作,不作为 Windows 服务工作

发布于 2025-01-07 15:35:42 字数 4287 浏览 0 评论 0原文

环境:Windows XP、Visual Studio 2010、安装 IIS。

我开发了一个 WCF 服务作为一个库,在 WCFSvcHost 中托管时可以正常工作;我可以连接到它,更新客户的服务参考,这样就可以了。

不过,我无法将其作为 Windows 服务托管。该服务安装正常,我可以附加到它并中断我的代码。为了调试托管,我已将代码移至 OnResume() (OnStart 不执行任何操作)。

这是我的 OnResume (名称已更改以保护无辜者):

protected override OnResume()
{
    if (_selfHost == null)
    {
        _selfHost = new ServiceHost(typeof(MyService));
        _selfHost.Open();
    }
}

当单步执行 Open() 方法时,我收到以下异常:

System.InvalidOperationException was unhandled by user code
  Message=The HttpGetEnabled property of ServiceMetadataBehavior is set to true and the HttpGetUrl property is a relative address, but there is no http base address.  Either supply an http base address or set HttpGetUrl to an absolute address.
  Source=System.ServiceModel
  StackTrace:
       at System.ServiceModel.Description.ServiceMetadataBehavior.EnsureGetDispatcher(ServiceHostBase host, ServiceMetadataExtension mex, Uri url, String scheme)
       at System.ServiceModel.Description.ServiceMetadataBehavior.CreateHttpGetEndpoints(ServiceDescription description, ServiceHostBase host, ServiceMetadataExtension mex)
       at System.ServiceModel.Description.ServiceMetadataBehavior.ApplyBehavior(ServiceDescription description, ServiceHostBase host)
       at System.ServiceModel.Description.ServiceMetadataBehavior.System.ServiceModel.Description.IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
       at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost)
       at System.ServiceModel.ServiceHostBase.InitializeRuntime()
       at System.ServiceModel.ServiceHostBase.OnBeginOpen()
       at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open()
       at MyService.StartService()
       at MyService.OnContinue()
       at System.ServiceProcess.ServiceBase.DeferredContinue()
  InnerException: 

更改我的配置文件似乎无法解决问题:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" />
  </startup>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="MyService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/MyService/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="MyLib.IMyService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="http://localhost:8732/MyService/mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True" />
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

作为测试,我尝试过将 httpGetEnabled 设置为 False 并删除 mex 端点,但这只会将问题转移到其他地方:错误消息消失并且服务启动,但我的客户端无法调用该服务:

System.ServiceModel.EndpointNotFoundException was caught
  Message=There was no endpoint listening at http://localhost:8732/MyService/ that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
[...]

  InnerException: System.Net.WebException
       Message=The remote server returned an error: (400) Bad Request.
       Source=System
       StackTrace:
            at System.Net.HttpWebRequest.GetResponse()
            at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
       InnerException: 

有帮助吗?

Environment: Windows XP, Visual Studio 2010, IIS NOT installed.

I've developed a WCF service as a library that works fine when hosted in WCFSvcHost; I can connect to it, update a client's service reference, the works.

I'm unable to to host it as a Windows Service, though. The service installs okay, I can attach to it and break in my code. In order to debug the hosting, I've moved the code to OnResume() (OnStart does nothing).

Here's my OnResume (names have been changed to protect the innocent):

protected override OnResume()
{
    if (_selfHost == null)
    {
        _selfHost = new ServiceHost(typeof(MyService));
        _selfHost.Open();
    }
}

When stepping over the Open() method, I get the following exception:

System.InvalidOperationException was unhandled by user code
  Message=The HttpGetEnabled property of ServiceMetadataBehavior is set to true and the HttpGetUrl property is a relative address, but there is no http base address.  Either supply an http base address or set HttpGetUrl to an absolute address.
  Source=System.ServiceModel
  StackTrace:
       at System.ServiceModel.Description.ServiceMetadataBehavior.EnsureGetDispatcher(ServiceHostBase host, ServiceMetadataExtension mex, Uri url, String scheme)
       at System.ServiceModel.Description.ServiceMetadataBehavior.CreateHttpGetEndpoints(ServiceDescription description, ServiceHostBase host, ServiceMetadataExtension mex)
       at System.ServiceModel.Description.ServiceMetadataBehavior.ApplyBehavior(ServiceDescription description, ServiceHostBase host)
       at System.ServiceModel.Description.ServiceMetadataBehavior.System.ServiceModel.Description.IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
       at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost)
       at System.ServiceModel.ServiceHostBase.InitializeRuntime()
       at System.ServiceModel.ServiceHostBase.OnBeginOpen()
       at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open()
       at MyService.StartService()
       at MyService.OnContinue()
       at System.ServiceProcess.ServiceBase.DeferredContinue()
  InnerException: 

No amount of changing my config file seems to solve the problem:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" />
  </startup>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="MyService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/MyService/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="MyLib.IMyService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="http://localhost:8732/MyService/mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True" />
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

As a test, I've tried to set httpGetEnabled to False and to remove the mex endpoint, but that only moved the problem elsewhere: the error message goes away and the service starts, but then my client can't call the service:

System.ServiceModel.EndpointNotFoundException was caught
  Message=There was no endpoint listening at http://localhost:8732/MyService/ that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
[...]

  InnerException: System.Net.WebException
       Message=The remote server returned an error: (400) Bad Request.
       Source=System
       StackTrace:
            at System.Net.HttpWebRequest.GetResponse()
            at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
       InnerException: 

Any help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温柔一刀 2025-01-14 15:35:42

知道了。

我错误地从配置文件中复制了相关部分,不是一次,而是两次(在 Windows 服务和控制台应用程序中)。

谢谢特里。你让我沿着正确的思路思考。

Got it.

I had incorrectly copied the relevant section from the config file, not once, but twice (both in the windows service and the console app).

Thanks Terry. You got me thinking along the right lines.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文