具有多个合同的 Mono WCF 休息服务“配置文件中未定义端点”

Posted

技术标签:

【中文标题】具有多个合同的 Mono WCF 休息服务“配置文件中未定义端点”【英文标题】:Mono WCF Rest Service With Multiple Contracts "no endpoints are defined in the configuration file" 【发布时间】:2020-07-15 12:25:48 【问题描述】:

我想通过 mono 托管具有多个合同的 WCF Rest 服务,每个合同都在单独的部分类中实现。我阅读了许多关于类似问题的帖子,但没有针对单声道的解决方案。我合并或至少测试了我能找到的所有建议,现在我的代码看起来很像其他解决方案,但不起作用。

该应用程序在我的本地机器上成功运行,但一旦我通过单声道部署它就会引发错误。

Service 'MyWebServiceEndpoint' 实现了多种 ServiceContract 类型,配置文件中没有定义端点。

这是合同的端点之一。所有其他人都非常喜欢这个。它们都是实现另一个合同的部分类 MyWebServiceEndpoint 。

namespace MyServer.MyEndPoints         
    public partial class MyWebServiceEndpoint : INotificationEndpoint 

        public string GetNotifications(int limit) 
            // Do stuff
        
    

    [ServiceContract]
    public interface INotificationEndpoint 

        [OperationContract]
        [WebGet]
        string GetNotifications(int limit);
    

我的 App.config 看起来像这样。我删除了 IP 和端口,因为它们是服务器地址。

<system.serviceModel>
<services>
  <service name="MyServer.MyEndPoints.MyWebServiceEndpoint" behaviorConfiguration="WebService.EndPoint">
    <host>
      <baseAddresses>
        <add baseAddress="http://ip:port>"/> 
      </baseAddresses>
    </host>
    <endpoint address="/message"
              binding="webHttpBinding"
              contract="MyServer.MyEndPoints.IMessageEndpoint" 
              behaviorConfiguration="WebBehavior"/>
    <endpoint address="/music"
              binding="webHttpBinding"
              contract="MyServer.MyEndPoints.IMusicEndpoint" 
              behaviorConfiguration="WebBehavior"/>
    <endpoint address="/notification"
              binding="webHttpBinding"
              contract="MyServer.MyEndPoints.INotificationEndpoint"                   
              behaviorConfiguration="WebBehavior"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>
<behaviors>
  <serviceBehaviors>        
    <behavior name="WebService.EndPoint">
      <serviceMetadata httpGetEnabled="True" />
      <serviceDebug includeExceptionDetailInFaults="True"/>
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="WebBehavior">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>

我像这样在 C# 中打开服务。

WebServiceHost = new WebServiceHost(typeof(MyWebServiceEndpoint));
WebServiceHost.Open();

我在单声道上收到的错误消息是:

Unhandled Exception:
System.InvalidOperationException: Service 'MyWebServiceEndpoint' implements multiple ServiceContract 
types, and no endpoints are defined in the configuration file. WebServiceHost can set up default 
endpoints, but only if the service implements only a single ServiceContract. Either change the 
service to only implement a single ServiceContract, or else define endpoints for the service 
explicitly in the configuration file. When more than one contract is implemented, must add base 
address endpoint manually

我希望你有一些提示或有人知道如何解决这个问题。感谢您阅读到这里。

【问题讨论】:

【参考方案1】:

我不熟悉 Mono,Mono 是否支持Webconfig 文件?我建议您以编程方式添加服务端点。

class Program
    
        /// <param name="args"></param>
        static void Main(string[] args)
        
            WebHttpBinding binding = new WebHttpBinding();
            Uri uri = new Uri("http://localhost:21011");
            using (WebServiceHost sh = new WebServiceHost(typeof(TestService),uri))
            
                sh.AddServiceEndpoint(typeof(ITestService), binding, "service1");
                sh.AddServiceEndpoint(typeof(IService), binding, "service2");
                ServiceMetadataBehavior smb;
                smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
                if (smb == null)
                
                    smb = new ServiceMetadataBehavior()
                    
                        HttpGetEnabled = true
                    ;

                    sh.Description.Behaviors.Add(smb);

                

                sh.Opened += delegate
                
                    Console.WriteLine("service is ready");
                ;

                sh.Closed += delegate
                
                    Console.WriteLine("service is closed");
                ;

                sh.Open();

                Console.ReadLine();
                sh.Close();
            
        
    
    [ServiceContract]
    public interface ITestService
    
        [OperationContract]
        [WebGet]
        string GetData(int id);
    
    [ServiceContract]
    public interface IService
    
        [OperationContract]
        [WebGet]
        string Test();
    

    public class TestService : ITestService,IService
    
        public string GetData(int id)
        
            return $"id,";
        
        public string Test()
        
            return "Hello " + DateTime.Now.ToString();
        
    

结果。 根据官方文档,我们最好不要使用Partial class。https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/multiple-contracts 此外,我们可以考虑为每个服务实现类启动多个服务主机。 如果问题仍然存在,请随时告诉我。

【讨论】:

谢谢。到目前为止,使用 WebConfig 并没有解决它。但是我在您的回答之后发现了一些进一步的信息以及一个工作示例,它的作用类似于我的目标。我还假设部分类可能是问题之一,但对于一项服务和一个端点,我仍然会收到错误。然而,我正在根据我找到的示例制定解决方案。如果我完成了,会保持最新状态。

以上是关于具有多个合同的 Mono WCF 休息服务“配置文件中未定义端点”的主要内容,如果未能解决你的问题,请参考以下文章

并排托管 WCF 肥皂和休息端点

WCF 休息服务不返回 JSON 数据。但它适用于 XML

WCF - 使用完全相同的数据合同的多个服务合同

有没有办法在 WCF 的数据合同中使用 DataMember 装饰多个属性?

一个 WCF 服务中的多个合同_但调用第二个合同时出错

WCF IIS 托管服务由单个服务实现的多个服务合同 - 如何通过配置在端点之间共享 uri