我正在尝试从使用fileless activation在IIS中托管的WCF服务中删除tempuri.org。我已按照here的说明操作了,当bindingNamespace
中的Web.config
属性出现时,我陷入困境,因为我正在使用无文件激活。
我的Web.config
仅包含:
<serviceActivations>
<add relativeAddress="Foo.svc"
service="BigCorp.Services.Foo, BigCorp.Services"
/>
</serviceActivations>
因此,我没有<endpoint>
节点可以设置bindingNamespace
。
怎么办?
答案 0 :(得分: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>
希望这有帮助。
答案 1 :(得分: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";
}
}
}
}
答案 2 :(得分:0)
在您的服务代码中,您指定:
[ServiceContract(Namespace="http://your-url")]
public interface IMyInterface { ... }
您还可以为数据合同指定它:
[DataContract(Namespace="http://your-url/data")]
public class MyData { ... }
答案 3 :(得分:0)
除了service/data contract namespaces的明显变化外,您还可以在Binding对象本身设置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的东西。
答案 4 :(得分:0)
最后,我使用了源自this example的自定义BindingNamespaceAttribute
。
答案 5 :(得分: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