【问题标题】:How to get rid of tempuri.org in WCF service created by SharePoint Service Factory如何摆脱 SharePoint 服务工厂创建的 WCF 服务中的 tempuri.org
【发布时间】:2010-10-06 15:42:18
【问题描述】:

我正在使用服务工厂类在 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 块

  <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 更新: 我试图派生 MultipleBaseAddressBasicHttpBindingServiceHostFactory 并在创建 ServiceHost 时添加端点绑定命名空间。这不会成功,因为端点集合在那个时间点是空的。

【问题讨论】:

  • 天妇罗到底是什么问题?它实际上是用于任何 XML 元素或属性,还是仅在包装器 WSDL 中使用?
  • 这不是因为这是一个问题,而是因为我想坚持为您的 Web 服务提供唯一命名空间/名称的最佳实践。

标签: wcf sharepoint


【解决方案1】:

一般来说,您需要在三个地方显式设置命名空间以摆脱 tempuri.org 的默认设置:

  • ServiceContract 属性(基于合同)
  • ServiceBehavior 属性(在实现中)
  • 配置文件中相关服务元素上的bindingNamespace。

    --larsw

【讨论】:

    【解决方案2】:

    感谢 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;
            }
        }
    }
    

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

    【讨论】:

    • 谢谢一百万!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多