2011-05-31 65 views
4

我試圖從我的WCF服務中刪除tempuri.org,使用fileless activation在IIS中託管。我按照here的說明操作,並且我遇到Web.config中的bindingNamespace屬性,因爲我正在使用無文件激活。如何在使用無文件激活時設置bindingNamespace?

Web.config僅僅包含:

<serviceActivations> 
    <add relativeAddress="Foo.svc" 
     service="BigCorp.Services.Foo, BigCorp.Services" 
     /> 
</serviceActivations> 

所以我沒有在其上設置bindingNamespace<endpoint>節點。

怎麼辦?

+0

您是否嘗試過任何解決方案? – Kiquenet 2015-04-09 17:15:54

回答

0

最後,我用了一個自定義BindingNamespaceAttribute,從this example派生。

0

在你的服務代碼,請指定:

[ServiceContract(Namespace="http://your-url")] 
public interface IMyInterface { ... } 

,你也可以指定它爲數據合同:

[DataContract(Namespace="http://your-url/data")] 
public class MyData { ... } 
0

另外的service/data contract namespaces了明顯的變化,您還可以設置a namespace上綁定對象本身以及服務描述上的命名空間:

Binding binding = new BasicHttpBinding(); 
binding.Namespace = "urn:binding_ns"; 
ServiceHost host = new ServiceHost(typeof(MyService), address); 
var endpoint = host.AddServiceEndpoint(typeof(IMyService), binding, ""); 
host.Description.Namespace = "urn:desc_ns"; 

後者是控制WSDL文檔本身的targetNamespace。

+0

無文件配置並不意味着代碼內配置;我沒有綁定對象。 – 2011-06-01 15:34:54

+1

下次您可能想讓問題更清楚。不過,我認爲我發佈的內容可能對面臨類似問題的其他人有用。 – tomasr 2011-06-01 21:34:55

3

更改綁定的命名空間,你可以使用自定義工廠(而不是默認的設置),您可以更改綁定的所有屬性:

<serviceActivations> 
    <add relativeAddress="Foo.svc" 
     service="BigCorp.Services.Foo, BigCorp.Services" 
     factory="BigCorp.Services.FooHostFactory, BigCorp.Services"/> 
    </serviceActivations> 

,工廠:

public class FooHostFactory : ServiceHostFactory 
{ 
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
    { 
     return new FooServiceHost(serviceType, baseAddresses); 
    } 
} 
public class FooServiceHost : ServiceHost 
{ 
    public FooServiceHost(Type serviceType, params Uri[] baseAddresses) 
     : base(serviceType, baseAddresses) { } 

    protected override void OnOpening() 
    { 
     base.OnOpening(); 
     foreach (ServiceEndpoint endpoint in host.Description.Endpoints) 
     { 
      if (!endpoint.IsSystemEndpoint) 
      { 
       endpoint.Binding.Namespace = "http://services.bigcorp.com/foo"; 
      } 
     } 
    } 
} 
+0

這實際上不起作用。當調用CreateServiceHost時,host.Description.Endpoints是空的。 – 2011-09-15 11:01:12

+0

對。我使用從工作服務(我可能使用記事本編寫的服務)複製的某些內容更新了代碼,並且在OnOpening方法中已經爲該服務讀取了配置。 – carlosfigueira 2011-09-15 23:40:33

4

您仍然可以使用<services>以及<endpoint>節點進行WCF無文件激活。看看下面的例子,我甚至修改了默認的wsHttpBinding來增加傳輸安全性並啓用默認行爲;全部用於「Module1.DES.ExternalDataService」服務的無文件激活。

<system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
     <binding messageEncoding="Mtom"> 
      <security mode="Transport"/> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceMetadata httpGetEnabled="true"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 

    <services> 
     <service name="Module1.DES.ExternalDataService"> 
     <endpoint binding="wsHttpBinding" bindingNamespace="" contract="Module1.DES.IExternalDataService"/> 
     </service> 
    </services> 

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"> 
     <serviceActivations> 
     <add relativeAddress="ExternalDataService.svc" service="Module1.DES.ExternalDataService"/> 
     </serviceActivations> 

    </serviceHostingEnvironment> 
    </system.serviceModel> 

希望這會有所幫助。

0

如果您通過serviceActivations配置元素使用WCF 4.0的無文件服務激活功能,那麼您可以在ServiceHost實現中重寫AddDefaultEndpoints基本方法。

using System; 
using System.ServiceModel; 
using System.ServiceModel.Description; 

namespace MyApp.WS.WCFServiceHost 
{ 

    public class MyHostFactory : ServiceHostFactory 
    { 
     protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
     { 
      return new EDOServiceHost(serviceType, baseAddresses); 
     } 
    } 

    public class MyServiceHost : ServiceHost 
    { 
     public EDOServiceHost(Type serviceType, params Uri[] baseAddresses) 
      : base(serviceType, baseAddresses) { } 


     public override System.Collections.ObjectModel.ReadOnlyCollection<ServiceEndpoint> AddDefaultEndpoints() 
     { 
      var endpoints = base.AddDefaultEndpoints(); 

      foreach (ServiceEndpoint endpoint in endpoints) 
      { 
       if (!endpoint.IsSystemEndpoint) 
       { 
        endpoint.Binding.Namespace = NamespaceConstants.MyNamespace; 
       } 
      } 

      return endpoints; 
     } 


    } 
} 

或者你可以只使用配置而已,唯一的缺點到是你違反了DRY原則略有因爲你現在有兩個點,以保持命名空間的字符串,一個在你的常量和一個在配置文件。

在下面的示例中,我使用WCFExtrasPlus行爲來「壓扁」WSDL。如果您部署到.net 4.5 IIS7服務器,則不需要此功能,因爲無論如何您都可以訪問平面WSDL,這是4.5框架中內置的新功能,我離題了。

該示例還假定這些合同有兩個服務合同和兩個服務行爲實現。

<system.serviceModel> 

    <services> 
     <service name ="MyApp.WS.ServiceBehaviour.Enquiries"> 
     <endpoint bindingNamespace="MyApp.WS" binding="basicHttpBinding" contract="MyApp.WS.ServiceContract.IEnquiries" /> 
     </service> 

     <service name ="MyApp.WS.ServiceBehaviour.CallLogging"> 
     <endpoint bindingNamespace="MyApp.WS" binding="basicHttpBinding" contract="MyApp.WS.ServiceContract.ICallLogging" /> 
     </service> 
    </services> 

    <serviceHostingEnvironment> 
     <serviceActivations> 
     <add relativeAddress="Enquiries.svc" 
      service="MyApp.WS.ServiceBehaviour.Enquiries" 
      /> 
     <add relativeAddress="CallLogging.svc" 
      service="MyApp.WS.ServiceBehaviour.CallLogging" 
       /> 
     </serviceActivations> 
    </serviceHostingEnvironment> 

    <extensions> 
     <behaviorExtensions> <!-- The namespace on the service behaviour, the service contract, the data contract and the binding must all be set to the same.--> 
     <add name="wsdlExtensions" type="WCFExtrasPlus.Wsdl.WsdlExtensionsConfig, WCFExtrasPlus, Version=2.3.1.8201, Culture=neutral, PublicKeyToken=f8633fc5451b43fc" /> 
     </behaviorExtensions> 
    </extensions> 

    <behaviors> 
     <endpointBehaviors> 
     <behavior> 
      <wsdlExtensions singleFile="true" /> 
     </behavior> 
     </endpointBehaviors> 
     <serviceBehaviors> 
     <behavior> 
      <!-- To avoid disclosing metadata information, 
      set the value below to false and remove the metadata endpoint above before deployment --> 
      <serviceMetadata httpGetEnabled="True"/> 
      <!-- To receive exception details in faults for debugging purposes, 
      set the value below to true. Set to false before deployment 
      to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="True"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

供參考的服務合同;

[ServiceBehavior(Namespace = NamespaceConstants.MyNamespace)] 
public class CallLogging : ICallLogging 
{ 
} 

[ServiceBehavior(Namespace = NamespaceConstants.MyNamespace)] 
public class Enquiries : IEnquiries 
{ 
} 

注意:命名空間名稱中不需要http://。它可以是你的項目的命名空間,如果你喜歡,即MyApp.MyProject.Somthing。請參閱URN

相關問題