WCF 4 - конечные точки мыла и REST - PullRequest
8 голосов
/ 05 апреля 2011

Я рассматривал использование шаблона приложения службы REST WCF для размещения всех моих веб-служб RESTful, однако я также хотел бы иметь возможность предоставлять свои службы WCF с помощью конечной точки SOAP.

Я легко могу заставить мои WCF RESTful-сервисы работать в WCF 4, используя следующий пример: http://christopherdeweese.com/blog2/post/drop-the-soap-wcf-rest-and-pretty-uris-in-net-4

Возможно ли это? Я полагаю, что в Global.asax должен быть способ подключить дополнительные конечные точки и указать, использует ли один элемент basicHttpBinding. Нужно ли мне не использовать шаблон приложения-службы WCF REST, создавать стандартное приложение-службу и подключать его через конфигурацию?

Спасибо за любую помощь.

Ответы [ 3 ]

6 голосов
/ 13 мая 2011

Хотя в большинстве случаев я бы не совмещал конечные точки REST и SOAP, но я согласен, что в некоторых случаях это необходимо.Ответ на вопрос: да, их можно смешивать.Вы можете использовать две опции:

Вызов в Global.asax.cs, который определяет маршрут для конечной точки REST

`RouteTable.Routes.Add(new ServiceRoute("Service1", new WebServiceHostFactory(),   typeof(Service1)))` 

, определяет, по существу, службу по адресу / Service1.Вы можете добавить новый «сервис», используя ту же реализацию сервиса, но используя другую фабрику хостов сервиса (вместо использования WebServiceHostFactory, которая определяет конечную точку REST, вы бы использовали свою собственную):

public class SoapServiceHostFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
        ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
        if (smb == null)
        {
            smb = new ServiceMetadataBehavior();
            host.Description.Behaviors.Add(smb);
        }

        smb.HttpGetEnabled = true;
        host.AddServiceEndpoint(serviceType, new BasicHttpBinding(), "soap");
        return host;
    }
}

И в global.asax.cs, RegisterRoutes:

    private void RegisterRoutes()
    {
        // Edit the base address of Service1 by replacing the "Service1" string below
        RouteTable.Routes.Add(new ServiceRoute("Service1", new WebServiceHostFactory(), typeof(Service1)));

        RouteTable.Routes.Add(new ServiceRoute("SoapService", new SoapServiceHostFactory(), typeof(Service1)));
    }
  • Если вы действительно хотите иметь один «логический» сервис с двумя конечными точками (я бы не рекомендовал, так как предыдущий подход простдостаточно), вы можете снова создать собственный ServiceHostFactory, затем на этой фабрике вы добавите две конечные точки: одну для REST (с использованием WebHttpBinding / WebHttpBehavior) и одну для SOAP (например, с помощью BasicHttpBinding).
2 голосов
/ 15 сентября 2011

Мне пришлось добавить конструктор на фабрику carlosfigueira, чтобы он строил конечную точку из интерфейса, а не из самой службы:

public class SoapServiceHostFactory : ServiceHostFactory
{
    private Type serviceInterfaceType;

    public SoapServiceHostFactory(Type serviceInterfaceType) 
    {
        this.serviceInterfaceType = serviceInterfaceType;
    }

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
        host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
        host.AddServiceEndpoint(serviceInterfaceType, new BasicHttpBinding(), "soap");
        return host;
    }
}
0 голосов
/ 16 мая 2011

У меня запущена веб-служба, где клиентам требуется как SOAP, так и REST-доступ.Вы можете определить свои шаблоны URL REST, используя атрибуты WebGet и WebInvoke.

[ServiceContract]
public interface IService
{
    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
    RS DoSomething(RQ request); 
}

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service : IService
{
    public RS DoSomething(RQ rq)
    {
        return new RS(rq);
    }
}

Затем просто сопоставьте конечные точки, как требуется в конфигурации

  <system.serviceModel>
    <services>
      <service name="Service" behaviorConfiguration="defaultBehavior">
        <endpoint address="soap11" binding="basicHttpBinding" contract="IService" behaviorConfiguration="soapBehavior" />
        <endpoint address="rest" binding="webHttpBinding" contract="IService" behaviorConfiguration="restBehavior"/>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="restBehavior">
          <webHttp faultExceptionEnabled="true" />
        </behavior>
        <behavior name="soapBehavior">
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="defaultBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true"  />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...