【问题标题】:WCF Multiple Endpoints is not workingWCF 多个端点不起作用
【发布时间】:2012-04-24 15:56:05
【问题描述】:

我试图让我的 WCF 服务具有可以通过代理客户端和 REST 调用调用的操作,我正在使用以下配置:

<services>
  <service behaviorConfiguration="SecureBehavior" name="Payment">
    <endpoint address="" binding="wsHttpBinding"  bindingConfiguration="secureWS" contract="IPayment"/>
    <endpoint address="rest" binding="webHttpBinding" behaviorConfiguration="webBehavior" contract="IPayment"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  </service>
  <bindings>
    <mexHttpBinding>
      <binding name="userMex"/>
    </mexHttpBinding>
    <wsHttpBinding>
      <binding name="secureWS">
        <security mode="Message">
          <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true"/>
        </security>
      </binding>
      <binding name="publicWS">
        <security mode="None"/>
      </binding>
    </wsHttpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
      <behavior name="SecureBehavior">
        <serviceMetadata httpGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="true"/>
        <serviceCredentials>
          <windowsAuthentication allowAnonymousLogons="false"/>
        </serviceCredentials>
      </behavior>
      <behavior name="PublicBehavior">
        <serviceMetadata httpGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="true"/>
        <serviceCredentials>
          <windowsAuthentication allowAnonymousLogons="true"/>
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
    <endpointBehaviors>
      <behavior name="webBehavior">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
</services>

这是我的代码:

[ServiceContract]
public interface IPayment
{
    [OperationContract]
    PaymentResult Finalize(string TransactionID, string CertificatePath);

    [OperationContract]
    [WebGet(UriTemplate = "rest")]
    System.IO.Stream GetPayment();
}

现在每当我运行我的服务时,我都会收到此错误:

合约“IPayment”的“Finalize”操作指定要序列化的多个请求主体参数,无需任何包装器元素。最多一个 body 参数可以在没有包装元素的情况下被序列化。删除额外的正文参数或将 WebGetAttribute/WebInvokeAttribute 上的 BodyStyle 属性设置为 Wrapped。

我希望在此处保留仅通过 .NET 客户端调用的 Finalize 操作和通过任何浏览器调用的 GetPayment 操作。

【问题讨论】:

    标签: wcf


    【解决方案1】:

    如果您不希望从通过 webhttp 端点连接的客户端调用您的 Finalize 方法,并且您不希望从通过 wshttp 连接的客户端调用 GetPayments,您可以简单地将合同一分为二。

    假设您在 IIS 中进行托管,您可能需要做一些小技巧来确保它可以正常工作。让我用问题中的细节举一个例子......

    首先这里是两个服务的代码...

    [ServiceContract]
    public interface IPayment
    {
        [OperationContract]
        [WebGet(UriTemplate = "rest")]
        System.IO.Stream GetPayment();
    }
    
    [DataContract]
    public class PaymentResult
    {
    }
    
    [ServiceContract]
    public interface IMakePayment
    {
        [OperationContract]
        PaymentResult Finalize(string TransactionID, string CertificatePath);
    }
    
    // Maybe you really should have the two services separate but if you do
    // want to implement them both in a single class you can do this
    public abstract class PaymentBase : IMakePayment, IPayment
    {
        // ... Implement both interfaces here
        public PaymentResult Finalize(string TransactionID, string CertificatePath)
        {
            return null;
        }
    
        public System.IO.Stream GetPayment()
        {
            return null;
        }
    }
    
    public class MakePayment : PaymentBase
    {
        // Empty
    }
    
    public class Payment : PaymentBase
    {
        // Empty
    }
    

    现在像这样创建两个 .svc 文件:

    MakePayment.svc

    <%@ ServiceHost Language="C#" Debug="true" Service="WebApplication1.MakePayment"  %>
    

    Payment.svc

    <%@ ServiceHost Language="C#" Debug="true" Service="WebApplication1.Payment" %>
    

    最后是system.servicemodel的配置:

    <system.serviceModel>
      <services>      
        <service behaviorConfiguration="SecureBehavior" name="WebApplication1.MakePayment">        
          <endpoint binding="wsHttpBinding" bindingConfiguration="secureWS" contract="WebApplication1.IMakePayment"/>
          <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" bindingConfiguration="userMex"/>
        </service>
        <service behaviorConfiguration="PublicBehavior" name="WebApplication1.Payment">
          <endpoint binding="webHttpBinding" behaviorConfiguration="webBehavior" bindingConfiguration="publicWS" contract="WebApplication1.IPayment"/>
        </service>      
      </services>
      <bindings>
        <mexHttpBinding>
          <binding name="userMex"/>
        </mexHttpBinding>
        <wsHttpBinding>
          <binding name="secureWS">
            <security mode="Message">
              <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true"/>
            </security>
          </binding>
        </wsHttpBinding>
        <webHttpBinding>
          <binding name="publicWS">
            <security mode="None"/>
          </binding>
        </webHttpBinding>
      </bindings>
      <behaviors>
        <serviceBehaviors>
          <behavior name="SecureBehavior">
            <serviceMetadata httpGetEnabled="true"/>
            <serviceDebug includeExceptionDetailInFaults="true"/>
            <serviceCredentials>
              <windowsAuthentication allowAnonymousLogons="false"/>
            </serviceCredentials>
          </behavior>
          <behavior name="PublicBehavior">
            <serviceMetadata httpGetEnabled="true"/>
            <serviceDebug includeExceptionDetailInFaults="true"/>
            <serviceCredentials>
              <windowsAuthentication allowAnonymousLogons="true"/>
            </serviceCredentials>
          </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
          <behavior name="webBehavior">
            <webHttp/>
          </behavior>
        </endpointBehaviors>
      </behaviors>
      <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
    

    你去 - 如果你连接到 /MakePayment.svc,你将通过 WSHTTP 连接并能够调用 FinalizePayment,如果你去 /Payments.svc/rest,它将调用 GetPayment 方法,你正在返回一个流。

    【讨论】:

    • 我是这样做的,但现在出现了一个新错误:找不到端点,知道吗?
    • 更新了一个更具体的例子
    • 现在迷路了 :) 让我遍历你的代码看看,还是谢谢你。
    猜你喜欢
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多