如何摆脱SharePoint Service Factory创建的WCF服务中的tempuri.org

时间:2010-10-06 15:42:19

标签: wcf sharepoint

我使用Service Factory类在SharePoint 2010上公开WCF服务,并且无法完全摆脱生成的WSDL中的tempuri.org命名空间。

以下是我的工作:

ISAPI文件夹中的svc文件

<%@ServiceHost
    Language="C#"
    Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    Service="MyService, [...]"   
%>

服务合约

using System.ServiceModel;

    namespace MyService
    {
        [ServiceContract(Namespace="http://myname.com")]
        interface IMyService
        {
            [OperationContract]
            string GetSomeDefinition();
        }
    }

服务实施

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using Microsoft.SharePoint.Client.Services;

    namespace MyService
    {
        [ServiceBehavior(Namespace = "http://myname.com")]
        [BasicHttpBindingServiceMetadataExchangeEndpointAttribute]
        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
        class MyService : IMyService
        {
            public string GetSomeDefinition()
            {
                // do some stuff...
                return result;
            }
        }
    }

WSDL

<wsdl:definitions name="MyService" targetNamespace="http://myname.com" [...]>
  <wsdl:import namespace="http://tempuri.org/" location="http://localhost/_vti_bin/myservice.svc/mex?wsdl=wsdl0" /> 
  [...]
</wsdl:definitions>

现在的问题是WSDL分为两部分。一个具有正确的新命名空间http://myname.com,另一个具有默认命名空间http://tempuri.org。通常,您可以通过在端点配置上使用bindingNamespace属性来消除它。但因为我使用的是服务工厂,所以我不能这样做。尝试在web.config中定义服务端点失败,并显示以下错误:绑定实例已与关联监听http://localhost/ ...

Web.config chunk

  <system.serviceModel>
    <services>
      <service name="MyService.MyService">
        <endpoint address="http://localhost/_vti_bin/myservice.svc" binding="basicHttpBinding" contract="MyService.IMyService" bindingNamespace="http://myname.com" />
      </service>
    </services>
  </system.serviceModel>

2010-10-07更新: 我试图在创建ServiceHost时派生MultipleBaseAddressBasicHttpBindingServiceHostFactory并添加端点绑定命名空间。这不成功,因为端点集合在那个时间点是空的。

2 个答案:

答案 0 :(得分:2)

通常,您需要三个位置来显式设置命名空间以摆脱tempuri.org默认值:

  • ServiceContract属性(合同上)
  • ServiceBehavior属性(在实施时)
  • 相关服务上的bindingNamespace&lt; endpoint /&gt;配置文件中的元素。

    - larsw

答案 1 :(得分:0)

我遇到了完全相同的问题,并设法解决了它,感谢Cameron Verhelst的这篇博文:http://cameron-verhelst.be/blog/2014/10/19/hosting-a-wcf-service-in-sharepoint-with-a-spcontext/(非常感谢他!)

我的服务的消费者不希望WSDL成为多部分,所以我必须正确配置我的服务命名空间。

关键是创建自己的服务主机和服务主机工厂,以便由服务主机修改自动创建的端点,并在svc文件中引用它。

这是我的:

<强> CustomMultipleBaseAddressBasicHttpBindingServiceHostFactory.cs

using System;
using System.ServiceModel;
using Microsoft.SharePoint.Client.Services;

public class CustomMultipleBaseAddressBasicHttpBindingServiceHostFactory : MultipleBaseAddressBasicHttpBindingServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        return new CustomMultipleBaseAddressBasicHttpBindingServiceHost(serviceType, baseAddresses);
    }
}

<强> CustomMultipleBaseAddressBasicHttpBindingServiceHostFactory.cs

using System;
using System.Linq;
using System.ServiceModel.Description;
using Microsoft.SharePoint.Client.Services;

public class CustomMultipleBaseAddressBasicHttpBindingServiceHost : MultipleBaseAddressBasicHttpBindingServiceHost
{
    public CustomMultipleBaseAddressBasicHttpBindingServiceHost(Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses)
    {
    }

    protected override void OnOpening()
    {
        base.OnOpening();

        string targetNamespace = ImplementedContracts.First().Value.Namespace;

        foreach (ServiceEndpoint endpoint in Description.Endpoints)
        {
            endpoint.Binding.Namespace = targetNamespace;
        }
    }
}

此服务主机允许强制端点的目标命名空间与指定的合同相同。