Extend the EDP To Track File Downloads
The possibilities for creating solutions with the Data Integration Toolset are almost limitless. With this in mind, one idea for creativity is tracking file downloads from SharePoint with some simple settings of the External Data Provider.
Let’s set up our scenario: A software company, SuperSoft stores and manages their software releases in SharePoint libraries and they give their customers access to these downloads based on their level of purchase. What SuperSoft currently doesn’t support internally is the tracking of who is actually downloading the software. EDP to the rescue!
To solve SuperSoft’s problem, we’ll first have them setup a Custom List in SharePoint where we’ll store the visitor’s information, we’ll create 3 columns: User, DownloadDate and FileDownloaded. DownloadDate will be a DateTime field with the default value being the current date and time. We’ll adjust our default view for our library to just show these three columns.

Next, we have SuperSoft create a couple of document libraries for storing our EDP files. We have them first create a Connections library that we’ll use to hold our EDP connection file and we have the create a Providers library that we’ll hold our EDP. Once these are created we’ll create our connection file and we’ll be using the EDP to connect to the SharePoint Lists web service.
Setting up our connection file is the key to getting the data that we are looking for. We create a new XML file and we we’ll configure it with the required data provider connection information for using a Web Service. In this connection file we will set it up to accept a parameter, in this case we’ll call it %sw%, which will be the actual URL to the file being downloaded and the connection file will also utilize the built-in CorasWorks parameter, CWUserID, which returns us the currently logged in user.
In order to setup our connection file, we need to have the Soap envelope and action information from the web service. The easiest way to do this when working with a .NET based web service, is to browse to the web service using Internet Explorer and get our information. To find the Lists web service, we type in our current site information and append _vti_bin/Lists.asmx to it… so our URL might look like: http://sp.mysite.com/software/_vti_bin/Lists.asmx, when we browse to this page it will return a list of public methods, we’ll find the one we need, the “UpdateListItems” method and copy the SOAP envelope and Action information. Once we have the SOAP envelope information in place, then we need to make a small adjustment so that it will correctly call the UpdateListItems method. More information on this can be found here: http://msdn.microsoft.com/en-us/library/lists.lists.updatelistitems.aspx
The end result is that our connection file will look like:
<?xml version="1.0" encoding="utf-8" ?>
<Data>
<Name>InsertVisitorInfo</Name>
<Default>true</Default>
<ConnectionType>Web Service</ConnectionType>
<RedirectTo>%sw%</RedirectTo>
<Request>%SiteURL%/_vti_bin/Lists.asmx</Request>
<SOAP>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<UpdateListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<listName>VisitorInfo</listName>
<updates>
<Batch OnError="Return">
<Method ID="1" Cmd="New">
<Field Name="User">%CWUserID%</Field>
<Field Name="FileDownloaded">%sw%</Field>
</Method>
</Batch>
</updates>
</UpdateListItems>
</soap:Body>
</soap:Envelope>
</SOAP>
<SOAPAction>http://schemas.microsoft.com/sharepoint/soap/UpdateListItems</SOAPAction>
<UseCurrentUserCredentials>2</UseCurrentUserCredentials>
<OutputType>text/xml</OutputType>
<Values>
<sw />
</Values>
</Data>
Notice that we use our %sw% parameter in a couple spots in the connection file, first you’ll see it in the <RedirectTo> node, this tells the EDP to redirect it’s web request to the supplied value, in this case it will be the path of the file to be downloaded. We also use the %sw% parameter to store that URL in our FileDownloaded column in the VisitorInfo custom list we created.
The hard part has now been created and configured, the next task we need to complete is to create a new Web Part Page (Site Actions > Create) and we’ll name ours VisitorsDP.aspx, we’ll use “Full Page, Vertical” and we’ll save it to our Provider library we created. Our new web part page will be opened in edit mode, so we’ll click on “Add a Web Part” and select our External Data Provider. Now we need to setup the EDP, so we click on “Edit” and select “Modify Shared Web Part” and we need to set two properties. First, under the “Source XML” group, we’ll set our “Source XML File Location” property to point to the connection file we created above:
<%SiteURL%>/Connections/VisitorSource.xml
Note: The %SiteURL% parameter is another built-in CorasWorks parameter that will return back the path of the current site that we are in.
The second property we need to set is under the “Output Properties” group and that is to check the “Output To XML” property. Once we have these set, we click “OK” and refresh our page… the page should return us information about our call to the web service with some error information that would look something like:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<UpdateListItemsResponse xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<UpdateListItemsResult>
<Results>
<Result ID="1,New">
<ErrorCode>0x00000000</ErrorCode>
<ID />
<z:row ows_ContentTypeId="0x010002C6DFE43EC9F549B89508FE53C52E4C" ows_User="CW\kdager" ows_DownloadDate="2009-04-07 15:30:06" ows_ID="2" ows_ContentType="Item" ows_Modified="2009-04-07 15:30:06" ows_Created="2009-04-07 15:30:06" ows_Author="90;#Kevin Dager" ows_Editor="90;#Kevin Dager" ows_owshiddenversion="1" ows_WorkflowVersion="1" ows__UIVersion="512" ows__UIVersionString="1.0" ows_Attachments="0" ows__ModerationStatus="0" ows_SelectTitle="2" ows_Order="200.000000000000" ows_GUID="{10485444-B8F2-49F8-81C2-52366E3DD1FB}" ows_FileRef="2;#dager/ws/Lists/VisitorInfo/2_.000" ows_FileDirRef="2;#dager/ws/Lists/VisitorInfo" ows_Last_x0020_Modified="2;#2009-04-07 15:30:06" ows_Created_x0020_Date="2;#2009-04-07 15:30:06" ows_FSObjType="2;#0" ows_PermMask="0x7fffffffffffffff" ows_FileLeafRef="2;#2_.000" ows_UniqueId="2;#{FE9CEC14-FC47-44C1-808B-A404EC29707D}" ows_ProgId="2;#" ows_ScopeId="2;#{D6B4CB69-82DC-4807-A211-E241DB00ADD6}" ows__EditMenuTableStart="2_.000" ows__EditMenuTableEnd="2" ows_LinkFilenameNoMenu="2_.000" ows_LinkFilename="2_.000" ows_ServerUrl="/dager/ws/Lists/VisitorInfo/2_.000" ows_EncodedAbsUrl="http://devrapps.corasworks.net/dager/ws/Lists/VisitorInfo/2_.000" ows_BaseName="2_" ows_MetaInfo="2;#" ows__Level="1" ows__IsCurrentVersion="1" xmlns:z="#RowsetSchema" />
</Result>
</Results>
</UpdateListItemsResult>
</UpdateListItemsResponse>
</soap:Body>
</soap:Envelope>
The reason this returns in this fashion is because we setup our EDP to expect a value being passed in, remember our %sw% parameter we configured?
Everything is now setup for our tracking purposes. What SuperSoft will do from this point, is on their main software download page, instead of setting the file download URL to the actual file itself, they would set their link to first call the EDP and pass in the URL of the file to download:
As soon as the end user clicks on the link to download the software, the EDP logs the needed info, calls the redirect which will immediately begin the download process, seemless to the end user. When we check our VisitorInfo list, we’ll see we have user info tracked!

Happy Coding!
