【问题标题】:How can basicHttpBinding, webHttpBinding & mexHttpBinding endpoints coexist in one WCF servicebasicHttpBinding、webHttpBinding 和 mexHttpBinding 端点如何共存于一个 WCF 服务中
【发布时间】:2011-11-30 09:54:20
【问题描述】:

我有一个 WCF 服务(目标 .NET 4),我需要公开 4 个端点:SOAP、POX、JSON 和 MEX。

我的配置文件如下所示:

<system.serviceModel>
    <!-- bindings -->
    <bindings>
      <basicHttpBinding>
        <binding name ="soapBinding">
          <security mode="None">
          </security>
        </binding>
      </basicHttpBinding>
      <webHttpBinding>
        <binding name="webBinding">
        </binding>
      </webHttpBinding>
    </bindings>
    <!-- behaviors -->
    <behaviors>
      <endpointBehaviors>
        <!-- plain old XML -->
        <behavior name="poxBehavior">
          <webHttp/>
        </behavior>
        <!-- JSON -->
        <behavior name="jsonBehavior">
          <enableWebScript  />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="defaultBehavior">
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="PubtranService.Service" behaviorConfiguration="defaultBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://192.168.1.102:8080/PT/"/>
          </baseAddresses>
        </host>
        <endpoint name="soap"
                  address="soap"
                  binding="basicHttpBinding"
                  bindingConfiguration="soapBinding"
                  contract="PubtranService.IService" />
        <endpoint name="pox"
                  address="pox"
                  binding="webHttpBinding"
                  bindingConfiguration="webBinding"
                  behaviorConfiguration="poxBehavior"
                  contract="PubtranService.IService" />
        <endpoint name="json"
                  address="json"
                  binding="webHttpBinding"
                  bindingConfiguration="webBinding"
                  behaviorConfiguration="jsonBehavior"
                  contract="PubtranService.IService" />
        <endpoint name="mex"
                  address="mex" 
                  binding="mexHttpBinding" 
                  bindingConfiguration=""
                  contract="IMetadataExchange"/>
      </service>
    </services>
  </system.serviceModel>

当我运行服务时,WCF 测试客户端返回 未能添加服务 带有 System.NullReferenceException 的消息 - 对象引用未设置为对象的实例 和堆栈跟踪:

System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata()
System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized()   System.ServiceModel.Description.ServiceMetadataExtension.WSMexImpl.GatherMetadata(String dialect, String identifier)   System.ServiceModel.Description.ServiceMetadataExtension.WSMexImpl.Get(Message request)
SyncInvokeGet(Object , Object[] , Object[] )
System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

但是 JSON 和 POX 端点是可访问的并且工作得很好。 另一方面,当我将它们从配置中注释掉时,WCF 测试客户端会正确显示 SOAP 服务。

目前服务中只实现了一种简单的方法:

[ServiceContract(Namespace="http://192.168.1.102:8080/")]
public interface IService
{

    [OperationContract]
    [WebGet]
    Tram[] GetOverview(string id);

}

为什么我要通过添加 pox 和 json 端点来阻止 mex 端点?

【问题讨论】:

    标签: wcf mex basichttpbinding webhttpbinding


    【解决方案1】:

    如果您的目标是为 xml 和 json 提供 1 种方法,我可以实现它,如下所示:

    <service name ="XMLService.MultipleEndpointService">        
            <endpoint name="soap" address="soap" binding="basicHttpBinding" contract="XMLService.IMultipleEndpointService" />
            <endpoint name="pox" address="pox" binding="webHttpBinding" behaviorConfiguration="web" contract="XMLService.IMultipleEndpointService" />
            <endpoint name="mex" address="mex"  binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
    
    <endpointBehaviors>
        <behavior name="web">          
          <webHttp/>          
        </behavior>        
     </endpointBehaviors>
    

    现在在您实现接口的类中,我执行了以下操作:

    public Tram[] GetOverview(string id)
            {
                IList<ContentType> acceptHeaderElements = WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements();
                for (int x = 0; x < acceptHeaderElements.Count; x++)
                {
                    string normalizedMediaType = acceptHeaderElements[x].MediaType.ToLowerInvariant();
                    switch (normalizedMediaType)
                    {
                        case "application/xml":
                            WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Xml;
                            break;
                        case "application/json":
                            WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Json;
                            break;
                    }
                }
    
                return new[] { new Tram() { TramName = "Tram 1" }, new Tram() { TramName = "Tram 2" } };
            }
    

    现在,当我使用 Fiddler 执行上述服务时:

    GET http://localhost/XMLService/multipleendpointservice.svc/pox/GetOverview HTTP/1.1
    User-Agent: Fiddler
    Host: localhost
    Accept: application/json
    

    我的回答是

    HTTP/1.1 200 OK
    Cache-Control: private
    Content-Length: 79
    Content-Type: application/json; charset=utf-8
    Server: Microsoft-IIS/7.5
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Date: Wed, 30 Nov 2011 11:39:16 GMT
    
    [{"<TramName>k__BackingField":"Tram 1"},{"<TramName>k__BackingField":"Tram 2"}]
    

    我表演的时候也是这样:

    GET http://localhost/XMLService/multipleendpointservice.svc/pox/GetOverview HTTP/1.1
    User-Agent: Fiddler
    Host: localhost
    Accept: application/xml
    

    我的回答是:

    HTTP/1.1 200 OK
    Cache-Control: private
    Content-Length: 334
    Content-Type: application/xml; charset=utf-8
    Server: Microsoft-IIS/7.5
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Date: Wed, 30 Nov 2011 11:39:09 GMT
    
    <ArrayOfTram xmlns="http://schemas.datacontract.org/2004/07/XMLService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Tram><_x003C_TramName_x003E_k__BackingField>Tram 1</_x003C_TramName_x003E_k__BackingField></Tram><Tram><_x003C_TramName_x003E_k__BackingField>Tram 2</_x003C_TramName_x003E_k__BackingField></Tram></ArrayOfTram>
    

    注意:Accept 标头可以不是 application/xml 或 application/json。在这种情况下你需要处理它。

    另一种选择是使用 WebServiceHostFactory 并使用具有 automaticFormatSelection 属性的 webHttpEndpoint 元素来执行上述操作

    【讨论】:

    • 感谢您的回答,但 XML 和 JSON 端点工作得很好,甚至在服务接口中没有一行代码 - 响应类型是自动正确确定的。我的问题是为什么当我添加 json 和 pox 端点时 mex 端点停止工作。
    • 我认为我们不能同时使用 webHttpbinding 的 Json 和 Xml 端点,因为您没有在 [WebGet] 属性中指定您的响应/请求类型。只需删除其中任何一个,您就可以看到您的肥皂和休息服务将按预期开始工作。我认为这一定是由于 webHttpBinding 正在使用的 ServiceHostFactory
    • Json 和 Xml 正在同时工作就好了。但是,如果我添加至少一个 XML 或 JSON,那么 SOAP 就会停止工作。
    • 您是否使用 .NET 4.0 框架运行上述内容。使用托管在 IIS 上的 .NET 3.5 一切正常,没有任何错误。访问 SOAP、POX、JSON 端点不会引发任何错误。似乎是 .NET 4 框架的问题。如果您可以投票,我已将此作为错误发布在 Microsoft 连接网站上,希望它会在即将发布的版本中得到修复。链接是connect.microsoft.com/wcf/feedback/details/711802/…
    【解决方案2】:

    好吧,使用不同名称 webBinding2 的绑定配置 webBinding 的简单复制将允许公开元数据。 至少我尝试过它并且它有效,尽管 WCF 的行为方式很奇怪。

        <endpoint name="pox"
                  address="pox"
                  binding="webHttpBinding"
                  bindingConfiguration="webBinding"
                  behaviorConfiguration="poxBehavior"
                  contract="PubtranService.IService" />
        <endpoint name="json"
                  address="json"
                  binding="webHttpBinding"
                  bindingConfiguration="webBinding2"
                  behaviorConfiguration="jsonBehavior"
                  contract="PubtranService.IService" />
    

    【讨论】:

      猜你喜欢
      • 2011-03-03
      • 2012-11-16
      • 1970-01-01
      • 1970-01-01
      • 2014-01-07
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多