One of the things I gave a lot of attention to recently was how to call a SharePoint-hosted, WCF service from within a SharePoint workflow. Specifically, I needed to send an email to an external email address – an user who doesn’t have a SharePoint account – a basic thing which doesn’t seem to be possible using the standard SendMail activity.
A few challenges immediately ensued:
– how the request is going to be authenticated ?
– how is the WCF going to look like – should it be SOAP or JSON or anything else?
– there are lots of samples on the internet about how to consume information from specifically REST or OData services, but very few and incomplete ones about how to actually invoke a service using POST method and send some long data with the request.
We created a SharePoint 2013 Farm Solution, containing two things: the service itself and the custom workflow activity. For the service I choose the JSON binding as it will be easier to deal with later from within the workflow. The custom activity in itself is also very simple – just calls the service.
Unfortunately, when calling a WCF service from workflow the authentication will not work. In order to be able to successfully make the call, the request will have to be anonymous. Even if you use the GetS2SSecurityToken activity and set a security token for the HttpSend, it will not work because the SPApplicationAuthentication HTTP Module only does that for a few well known endpoints: /_vti_bin/sites.asmx, /_vti_bin/client.svc, /_vti_bin/listdata.svc, /_api/ and /_vti_bin/wopi.ashx, and there’s no easy way to extend that list.
To successfully make the call, you will have to add the Authorization: header with an empty value to the requests.
Another thing to observe is the naming for the parameters when calling the method. The names must match, or an URI template must be specified (for REST calls) to create the mappings between incoming DynamicValues and the actual method parameters. If the names don’t match, the parameters will be passed default values.
For the activity to nicely display in the SharePoint Designer 2013, the .action4 file needs to be edited and parameters defined.
Define service contract, and data structures.
Use the “WebUri” activity to get the webUri you’re going to need to base your service endpoints.
Define a DynamicValue variable, and name it like the formal parameter in the service data contract’s method (in our case, “emailProperties”)
Use the “BuildDynamicValue” activity to initialize it.
Model the BuildDynamicValue’s properties after your data structure, making sure the property names and their types also match the ones in the data structure (EmailProperties class).
Use the “HttpSend” activity to call the method.
Set the Method to POST, RequestContent to emailProperties variable, RequestHeaders as below, and the Uri to webUri + ‘/_vti_bin/SendEmail/SendEmail.svc/SendEmail” – that is, the method URI.
Edit the .action4 file and add support for parameter binding and designer:
Download SharePointWFSendMail sample code.
What do you think?