SharePoint 2010 Web Service的MultipleBaseAddressBasicHttpBindingServiceHostFactory或WebScriptServiceHostFactory?

时间:2010-07-30 21:55:35

标签: .net wcf sharepoint sharepoint-2010

在创建在SharePoint 2010上运行的新服务时,人们似乎通常使用Sharepoint MultipleBaseAddressBasicHttpBindingServiceHostFactory

但是,我想使用标准的.net / WCF WebScriptServiceHostFactory,因为这通过使用/ js调用服务URL来为我提供JavaScript代码。

我的服务类本身仍然使用所需的属性进行修饰:

[BasicHttpBindingServiceMetadataExchangeEndpoint]
[AspNetCompatibilityRequirements(RequirementsMode =
         AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(Namespace = "http://mycompany/namespace")]
public class MyService : IMyServiceContract

整个服务实际上运作正常,但我只是想知道真正的差异是什么? SharePoint ServiceHostFactory会给我什么?

1 个答案:

答案 0 :(得分:14)

这是一个很好的问题!我的好奇心终于好起来了,我开始在Reflector中四处寻找。这不是权威的最终答案,但我认为你会对我学到的东西感兴趣。

首先关闭:MultipleBaseAddressBasicHttpBindingServiceHostFactory只生成MultipleBaseAddressBasicHttpBindingServiceHost个对象; WebScriptServiceHostFactory只生成WebScriptServiceHost个对象。

两个主机都继承System.ServiceModel.ServiceHost,因此他们拥有健全的共同基础。幸运的是,这减少了我们必须检查的代码占用空间的大小,以便进行公平的比较。

现在,尽管每个类中没有太多新代码,但它们会迅速向不同方向分支。看一下OnOpening()实现。

WebScriptServiceHost我们有:

base.OnOpening();
WebServiceHost.AddAutomaticWebHttpBindingEndpoints(
    this,
    base.ImplementedContracts,
    SR2.GetString(SR2.JsonWebScriptServiceHostOneServiceContract, base.ImplementedContracts.Count));
foreach (ServiceEndpoint endpoint in base.Description.Endpoints)
{
    if (endpoint.Binding != null &&
        endpoint.Binding.CreateBindingElements().Find<WebMessageEncodingBindingElement>() != null &&
        endpoint.Behaviors.Find<WebHttpBehavior>() == null)
    {
        endpoint.Behaviors.Add(new WebScriptEnablingBehavior());
    }
}

除非我弄错了,读取行endpoint.Behaviors.Add(new WebScriptEnablingBehavior());负责您想要的网址行为(/js)。

现在,在MultipleBaseAddressBasicHttpBindingServiceHost中,我们有(缩写):

ClientServiceHost host = ClientServiceHost.CreateServiceHost();
this.CreateEndpoints();
base.OnOpening();
host.OnServiceHostOpeningInternal(this);

WebServiceHost.AddAutomaticWebHttpBindingEndpoints()this.CreateEndpoints()之间的差异对我来说并不十分清楚。我的印象是SharePoint主机包含对不同身份验证模型的更多自动配置支持。

ClientServiceHost.CreateServiceHost()是一种工厂方法,它根据web.config部分ClientServiceHost中列出的类型创建microsoft.sharepoint.client/serverRuntime对象。

OnServiceHostOpeningInternal()方法只是将调用转发给主机的OnServiceHostOpening()方法。查看默认安装的web.config,我们找到服务主机类型的程序集限定名称,我们可以从中检查该方法:

<serverRuntime>
  <hostTypes>
    <add type="Microsoft.SharePoint.Client.SPClientServiceHost, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  </hostTypes>
</serverRuntime>

这里有趣的地方。 OnServiceHostOpening()方法如下所示:

[SharePointPermission(SecurityAction.Demand, ObjectModel=true)]
protected override void OnServiceHostOpening(ServiceHost serviceHost)
{
    if (serviceHost != null)
    {
        SPUtility.ConfigServiceHostIfClaimsAuth(serviceHost);
    }
}

进一步深入研究,我们看到了围绕配置主机进行基于声明的身份验证的一系列逻辑。

啊哈!有一点值得注意。除非我弄错了,WebScriptServiceHost中没有基于声明的身份验证支持。

结论

也许您没有使用基于声明的身份验证。如果是这样,您可能会发现使用WebScriptServiceHost很好。但是,如果我编写该服务,我将创建一个继承Microsoft类型的新主机和主机工厂,并查看是否可以使用endpoint.Behaviors.Add(new WebScriptEnablingBehavior()创建/ js扩展。可能发生的最糟糕的事情是它不起作用。另一方面,如果它确实有效,您可以期望拥有一个支持终端首选项的高度SP兼容的服务主机工厂。

我希望这会有所帮助。