2011-05-31 42 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

相关问题