简体   繁体   English

WCF 4 - Soap和REST端点

[英]WCF 4 - Soap and REST endpoints

I was looking at using the WCF REST Service Application template to host all of my RESTful web services, however, I would also like to be able to expose out my WCF services with a SOAP endpoint. 我正在考虑使用WCF REST服务应用程序模板来托管我的所有RESTful Web服务,但是,我也希望能够使用SOAP端点公开我的WCF服务。

I can easily get my WCF RESTful services working in WCF 4 using the following example: http://christopherdeweese.com/blog2/post/drop-the-soap-wcf-rest-and-pretty-uris-in-net-4 我可以使用以下示例轻松地在WCF 4中使用WCF RESTful服务: http//christopherdeweese.com/blog2/post/drop-the-soap-wcf-rest-and-pretty-uris-in-net-4

Is this possible? 这可能吗? I would imagine there should be a way in the Global.asax to wire up additional endpoints and specify if one is using basicHttpBinding. 我想在Global.asax中应该有一种方法可以连接其他端点并指定是否使用了basicHttpBinding。 Do I need to not use the WCF REST Service Application template and create a standard Service Application and wire it all up via the config? 我是否需要不使用WCF REST服务应用程序模板并创建标准服务应用程序并通过配置将其连接起来?

Thanks for any assistance. 谢谢你的帮助。

Although in most cases I wouldn't mix REST and SOAP endpoints, but I agree that in certain cases it's necessary. 虽然在大多数情况下我不会混用REST和SOAP端点,但我同意在某些情况下它是必要的。 The answer to the question: yes, it's possible to mix them. 这个问题的答案是:是的,可以将它们混合起来。 There are two options you can use: 您可以使用两个选项:

The call in Global.asax.cs which defines the route for the REST endpoint Global.asax.cs中的调用,它定义了REST端点的路由

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

defines essentially a service at the address /Service1. 在地址/ Service1本质上定义了一个服务。 You can add a new "service", using the same service implementation, but using a different service host factory (instead of using WebServiceHostFactory, which defines a REST endpoint, you'd use your own): 您可以使用相同的服务实现添加新的“服务”,但使用不同的服务主机工厂(而不是使用定义REST端点的WebServiceHostFactory,您可以使用自己的):

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;
    }
}

And in global.asax.cs, RegisterRoutes: 在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)));
    }
  • If you actually want to have one "logical" service with two endpoints (I wouldn't recommend, since the previous approach is simple enough), you can again create a custom ServiceHostFactory, then in that factory you'd add two endpoints: one for REST (using WebHttpBinding/WebHttpBehavior), and one for SOAP (using BasicHttpBinding, for example). 如果你真的想要一个带有两个端点的“逻辑”服务(我不建议,因为前面的方法很简单),你可以再次创建一个自定义的ServiceHostFactory,然后在那个工厂你要添加两个端点:一个用于REST(使用WebHttpBinding / WebHttpBehavior),一个用于SOAP(例如,使用BasicHttpBinding)。

I had to add a constructor to carlosfigueira's factory so it builds the endpoint from the Interface and not the Service itself: 我不得不在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;
    }
}

I have a web service running where clients require both SOAP and REST access. 我有一个运行Web服务,客户端需要SOAP和REST访问。 You can define your REST URL templates using the WebGet and WebInvoke attributes. 您可以使用WebGet和WebInvoke属性定义REST URL模板。

[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);
    }
}

Then simply map the endpoints as required in the config 然后只需在配置中根据需要映射端点

  <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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM