2011-11-30 62 views
2

我有一個WCF服務(目標.NET 4),我需要公開4個端點:SOAP,POX,JSON & MEX。如何basicHttpBinding,webHttpBinding和mexHttpBinding端點共存於一個WCF服務

我的配置文件看起來像這樣:

<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 Test Client正確顯示SOAP服務。

目前只有一個在服務中實現簡單的方法:

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

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

} 

爲什麼我剎車加入痘和JSON端點MEX終結?

回答

3

如果你的目標是擁有1層的方法,以服務爲XML和JSON我可以實現它,如下圖所示:

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

現在,當我使用招上述服務執行GET:

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

我的[R esponse是

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報頭可以比應用/ xml或application/JSON其他。在這種情況下,你需要處理它。

另一種方法是使用WebServiceHostFactory和使用具有automaticFormatSelection屬性webHttpEndpoint元件來執行上述動作

+0

謝謝您的回答,但XML和JSON端點工作得很好,甚至在服務界面中甚至沒有一行代碼 - 響應類型自動正確確定。 我的問題是爲什麼mex端點停止工作,當我添加json和pox的時候。 – krzysztofkarolczak

+0

我想我們不能同時使用WebHttpbinding和JHL和Xml端點,因爲您尚未在[WebGet]屬性中指定您的響應/請求類型。只要刪除其中一個,你就可以看到你的肥皂和休息服務將按預期開始工作。我認爲這一定是由於WebHttpBinding – Rajesh

+0

所使用的ServiceHostFactory,Json和Xml同時工作得很好。但是如果我添加至少一個XML或JSON,則SOAP停止工作。 – krzysztofkarolczak

0

那麼,綁定配置webBinding的簡單重複具有不同名稱webBinding2將允許暴露的元數據。 至少我試了一下,它的工作,雖然這是奇怪的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" /> 
相關問題