Mono WCF Rest Service с несколькими контрактами "конечные точки не определены в файле конфигурации" - PullRequest
1 голос
/ 03 апреля 2020

Я хочу разместить WCF Rest Service с несколькими контрактами через моно, каждый из которых реализован в отдельном частичном классе. Я прочитал много постов на подобные проблемы, но не было решения для моно. Я включил или, по крайней мере, протестировал все предложения, которые смог найти, и теперь мой код во многом похож на другие решения, но не работает.

Приложение успешно работает на моем локальном компьютере, но выдает ошибку, когда я его развертываю via mono.

Служба 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 Ответ

0 голосов
/ 10 апреля 2020

Я не знаком с 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();
        }
    }

Результат.
enter image description here
Согласно официальной документации, нам лучше не использовать Partial class.
https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/multiple-contracts
Кроме того, мы могли бы рассмотреть возможность запуска хоста с несколькими сервисами для каждого реализованного класса сервиса.
Не стесняйтесь, дайте мне знать, если проблема все еще существует.

...