When it comes to creating a new Service running on SharePoint 2010, people seem to usually use the Sharepoint MultipleBaseAddressBasicHttpBindingServiceHostFactory.
However, I would like to use the standard .net/WCF WebScriptServiceHostFactory instead because this gives me JavaScript code by calling the Service URL with /js.
My Service Class itself is still decorated with the required Attributes:
[BasicHttpBindingServiceMetadataExchangeEndpoint]
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(Namespace = "http://mycompany/namespace")]
public class MyService : IMyServiceContract
The whole Service actually works fine, but I just wonder what the real differences are? What would the SharePoint ServiceHostFactory give me?
This is a great question! My curiosity finally got the better of me, and I started poking around in Reflector. It's not the authoritative final answer, but I think you'll be interested in what I learned.
First off: MultipleBaseAddressBasicHttpBindingServiceHostFactory
simply generates MultipleBaseAddressBasicHttpBindingServiceHost
objects; WebScriptServiceHostFactory
simply generates WebScriptServiceHost
objects.
Both hosts inherit System.ServiceModel.ServiceHost
, so they have a healthy base of common ground. Lucky for us, this reduces the size of the code footprint we must inspect to get a fair comparison.
Now, though there's not much new code in each class, they quickly branch off in different directions. Take a look at the OnOpening()
implementations.
In WebScriptServiceHost
we have:
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());
}
}
Unless I am mistaken, the line reading endpoint.Behaviors.Add(new WebScriptEnablingBehavior());
is responsible for the URL behavior (/js
) you want.
Now, in MultipleBaseAddressBasicHttpBindingServiceHost
, we have (abbreviated):
ClientServiceHost host = ClientServiceHost.CreateServiceHost();
this.CreateEndpoints();
base.OnOpening();
host.OnServiceHostOpeningInternal(this);
The differences between WebServiceHost.AddAutomaticWebHttpBindingEndpoints()
and this.CreateEndpoints()
were not abundantly clear to me. I got the impression that the SharePoint host contained more automatic configuration support for different authentication models.
ClientServiceHost.CreateServiceHost()
is a factory method that creates a ClientServiceHost
object based on a type listed in the web.config section microsoft.sharepoint.client/serverRuntime
.
The OnServiceHostOpeningInternal()
method simply forwards the call to the host's OnServiceHostOpening()
method. Looking at the web.config of a default install, we find the assembly qualified name for the service host type, from which we can inspect the method:
<serverRuntime>
<hostTypes>
<add type="Microsoft.SharePoint.Client.SPClientServiceHost, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
</hostTypes>
</serverRuntime>
Here's where it gets interesting. The OnServiceHostOpening()
method looks like this:
[SharePointPermission(SecurityAction.Demand, ObjectModel=true)]
protected override void OnServiceHostOpening(ServiceHost serviceHost)
{
if (serviceHost != null)
{
SPUtility.ConfigServiceHostIfClaimsAuth(serviceHost);
}
}
Drilling in further, we see a metric boatload of logic surrounding configuring a host for claims-based authentication.
Aha! There is a difference worth noting. Unless I'm mistaken, there's no claims-based authentication support in WebScriptServiceHost
.
Perhaps you are not using claims-based authentication. If so, you might find that using WebScriptServiceHost
is fine. However, were it me writing the service, I'd create a new host and host factory inheriting the Microsoft types, and see if I could create the /js extension by using endpoint.Behaviors.Add(new WebScriptEnablingBehavior()
. The worst thing that could happen is that it wouldn't work. On the other hand, if it does work, you could expect to have a highly-SP-compatible service host factory that supports your endpoint preferences.
I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With