3

I often create WCF services that relies on out-of-the-box service factory (Microsoft.SharePoint.Client.Services.MultipleBaseAddressWebServiceHostFactory).

This is nice, because there's no web.config modification to apply.

However, is there any way to hook all requests?

For example, I would like to call SPUtility.ValidateFormDigest each time a service call is made.

Instead of duplicating the call to this method in each operation of my service, I'd like to add custom behavior. But I didn't found how to do that.

Any advise?

1 Answer 1

2

After some tests and issues, I finally discovered the correct way to reach my goal.

The idea is to attach a custom service behavior.

Here is the code of the behavior:

internal class ValidateSPFormDigestAttribute : Attribute, IServiceBehavior
{
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)        {        }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase host)
    {
        foreach (ChannelDispatcher cDispatcher in host.ChannelDispatchers)
        {
            foreach (EndpointDispatcher eDispatcher in cDispatcher.Endpoints)
            {
                eDispatcher.DispatchRuntime.MessageInspectors.Add(new ValidateSPFormDigestInspector());
            }
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)        {        }
}

internal class ValidateSPFormDigestInspector : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {

        if (!SPUtility.ValidateFormDigest())
        {
            throw new FaultException(new FaultReason("Invalid form digest token"));
        }

        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)  {        }
}

Then I can simply attach my behavior using the attribute:

[BasicHttpBindingServiceMetadataExchangeEndpoint]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ValidateSPFormDigest]
public class MyService : IWidgetAdminService

The benefits is that it does not require a custom servicehost factory.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.