



This post applies to Microsoft Office SharePoint Server 2007, WSS 3.0, Adobe LiveCycle, and PDF Forms
Scenario: Many organizations use Adobe PDF forms for employees to submit organizational forms for various business processes. It’s easy to configure these forms to submit the data in an e-mail message or send it to a SQL Server database. Submitting data is usually not the only thing required in the business process of the form. Once the data gets submitted via e-mail or database, there is usually some type of workflow involved in the business process. Adobe has a product called Adobe LiveCylcle ES that has a workflow engine that can be used to process information within an organization via Adobe Forms. Adobe LiveCycle ES is an incredible product but it is very expensive and you may not have it available within your organization. As an alternative, it is possible to post data from an Adobe PDF form and submit it to a SharePoint List. It is actually a very easy process. So….. How do you solve this?
Solution: First of all, I’m not sure why – but there is not much to find out there on this problem. I’m not sure exactly why. If you learn this technique, you could easily create very dynamic forms using Adobe LiveCycle Designer that can meet difficult requirements and leverage the use of SharePoint for data storage and Workflow processes. This Adobe blog post helped me with this process: Click Here to Read an Adobe Blog Post
You could easily read the post from the link above, so I’m going to explain it to you from my perspective.
Basically, to get Adobe PDF forms to communicate with a SharePoint List you need a 3 layer architecture.
LAYER 1: Adobe Form with a Submit button that is configured to submit data as XML and send the XML data to the http path of an .ashx file that is stored in the 12 hive (or another location) on a SharePoint server
LAYER 2: An .ashx file is created using Visual Studio (or any text editor) and stored in the 12 hive (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\Whatever_You_Want_To_Call_This_Subdirectory) of the SharePoint Server.
LAYER 3: A Custom SharePoint List is created that has fields that match the fields of the Adobe Form.
Now I will explain each of these 3 Layers in more detail.
LAYER 1 (The Adobe Form):
First, you will want to use Adobe LiveCycle Designer to design the fields for your form. Just create a simple Text field called “Title” and a “Submit” button on the form. Then configure the Submit button to submit the data as XML. When configuring the submit button for XML, it will ask you for a desination URL to post your data. This is where you will paste the http: path from SharePoint to locate the .ashx file. If you stored the file in a subdirectory of the LAYOUTS directory of the 12 hive, it would be something like: http://servername/sites/sitecollectionname/_layouts/whatever_subdirectory/whatever.ashx
Now your form is prepared for data submission to a SharePoint List using an HttpHandler. Now lets keep going here.
LAYER 2 (The HTTPHandler – .ashx file)
You will need to create an HTTPHandler (.ashx) file with Visual Studio to handle accepting XML data from the Adobe PDF form and send it to the SharePoint List. The HTTPHandler will basically be used as the “middle man” to handle the exchange of the data. The file can be stored in the 12 hive of the SharePoint server so that it can be visible by all site collections within the SharePoint Farm. To use the 12 hive, you will need to create a subdirectory in the following path: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\Whatever_Subdirectory
You could easily just store .ashx file in the LAYOUTS directory, but its best practice not to do this so that you don’t risk replacing a file with the same name which could cause your SharePoint farm to become unstable.
The easiest way to create an .ashx file in Visual Studio is just to create a Web Application project using C#/ASP.NET. Then add a “New Item” as a basical HTML page. Then just rename the HTML Page with a .ashx file extension. There are other ways but this is easy enough.
Now let’s take a look at the anatomy of this .ashx file. First of all, you will be programming against SharePoint Services to get the data to the SharePoint list. So let’s look at a sample ASP.NET/C# script:
CODE ::
<%@ Assembly Name=”Microsoft.SharePoint,Version=12.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c” %>
<%@ WebHandler Language=”C#” Class=”put_data_in_sp_list” %>
using System;
using System.Web;
using Microsoft.SharePoint;
using System.Xml;
public class put_data_in_sp_list : IHttpHandler {
public void ProcessRequest (HttpContext context) {
SPSite site = SPContext.Current.Site;
SPWeb web = site.OpenWeb();
try
{
string rawXML = “”;
XmlTextReader reader = new XmlTextReader(context.Request.InputStream);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
string _xmlString = xmlDoc.InnerXml;
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
string _fileTime = DateTime.Now.ToFileTime().ToString();
byte[] docAsBytes = encoding.GetBytes(_xmlString);
//Insert Document
web.AllowUnsafeUpdates = true;
// Here is the name of your Custom SharePoint List
SPList list = web.Lists["TestList"];
SPListItem item = list.Items.Add();
// Here is the name of your SharePoint Field that you will be sending the data from the first field of your Adobe Form
item["Title"] = xmlDoc.GetElementsByTagName(”Title”).Item(0).InnerText;
// Now Update the SharePoint List with the Data
item.Update();
}
catch (Exception ex)
{
context.Response.Write(ex.Message);
}
}
// The HTTPHandler must have these lines
public bool IsReusable {
get {
return false;
}
}
}
:: END OF CODE
Notice that this script is using a single text field in an Adobe form then sending the XML data to a Custom SharePoint list called “TestList” in the “Title” field using SharePoint Services. If you have ever programmed C# scripts against SharePoint Services, you can see how this technique is EXTREMELY powerful. Since the referenced class above is “put_data_in_sp_list”, then obviously your .ashx file will be called put_data_in_sp_list.ashx .
LAYER 3 (Custom SharePoint List):
The final piece of this architecture is the Custom SharePoint List. If you are working off of the example above, obviously you will need to create a Custom SharePoint List called “TestList” and just use the “Title” field.
Conclusion:
Now that you have all 3 layers in place, you can now Preview your Adobe PDF form in Adobe LiveCycle Designer and enter some text in the text field. Then hit the Submit button. Your data will now be sent to the HTTPHandler, then added as a new item in the SharePoint “TestList”.
Once you have successfully tested data going from the Adobe PDF form to the custom SharePoint List, you are now ready to create your custom workflow on the SharePoint list. Just use SharePoint Designer to create the workflow to meet your business process needs and set it to kick off when a new item is added to the “TestList”. Install the worklfow on the “TestList” and now you have an end-to-end business solution using an Adobe PDF form to submit data to a SharePoint list while leveraging the Workflow capabilities of SharePoint.










More Options ...

Categories
Tag Cloud
Blog RSS
Comments RSS

Void
Life « Default
Earth
Wind
Water
Fire
Light 
7:21 am - July 29th, 2009
Thank you for posting this but it looks like I’m having the same issue as this guy:
http://www.sharepointblogs.com/forums/t/21869.aspx
I followed you recommendations and I am still getting “Authorization Failure” after going through your 4 points to look at.
Any other ideas?
For testing purposes I have basically copied and pasted your code and am using a SP list with a single “title” data column and a single field in my PDF form called “title”
8:02 am - July 29th, 2009
Also, if i browse to the handler I get the following (not sure if this helps)
The given assembly name or codebase was invalid. (Exception from HRESULT: 0×80131047)
4:13 pm - July 30th, 2009
I think it’s worth you trying to just create a basic HttpHandler to work within SharePoint first. Take a look at this MSDN article: Click Here. This is sort of a Hello World HttpHandler that displays a message if you navigate directly to the .ashx file. MAKE NOTE THOUGH: The Code in this MSDN article has a typo in the code that is missing a semi-colon after the line that includes the text/plain reference. Make sure you take a close look at the comments below the article. If you can successfully get this HttpHandler to work, you may be headed in the right direction. This should be able to eliminate the possibility of permission issues, improper Assembly references, etc…
2:44 pm - July 31st, 2009
I was able to get that to work and then your code worked! …kind of.
I got a new error in the sharepoint logs and the .aspx page returns an “unknown error” (I love how specific they are)
The log writes:
Exception Type: System.Web.HttpException Exception Message: The directive ‘webhandler’ is unknown.
The directive is written JUST like your example but I am clueless on where to start with this. It seems like I’m ALMOST there.
…and yes, I am admitting that I am total novice at this.
4:58 pm - July 31st, 2009
Glad to here you are making progress! To address your error – take a close look at this line in your code: < %@ WebHandler Language=”C#” Class=”put_data_in_sp_list” %>
Make sure this line matches the name of your Class declared below. Also – just in case you have some type of syntax error, take a look at this MSDN article: Click Here
9:32 am - August 3rd, 2009
It’s it’s not one thing it’s another! LOL
I appreciate your help so far but after fixing this (there was a simple typo in my code) I’m now getting all of the source code displayed as plain text when viewing the .aspx code.
I’ve reinstalled ASP, doubled checked my scripting settings, MIME types, and successfully launched other .aspx pages.
I’ll let you know if I get this fixed!
2:01 pm - August 5th, 2009
I’m sorry to sit here and clutter up your blog with responses but this is EXACTLY what we’ve been needing to a year now and I’m elated to get this thing running.
New error after fixing previous error. I have copy and pasted your code and named everything exactly how you have it.
Now getting in the logfile:
“Exception Message: Object reference not set to an instance of an object.”
Also, this seems odd but when I copy your code into visual studio 2008 I have to change/retype all of the ” marks to get them to accept. It seems your site formats quotations as opening and closing marks instead of the generic ‘ ” ‘ mark.
When you try to browse the site, you get “unknown error.”
You really need a “donate” button on the bottom of your site!
3:36 pm - August 5th, 2009
Unrelated comment but you have very polished design going on here
I actually arrived here because somebody is having problems getting your code going – maybe you can help them out?
http://forums.asp.net/t/1455560.aspx
11:09 am - August 10th, 2009
Hi,
This post was quite useful for me. However after copy and paste the code given, I was getting “unknown error”. After a while I figured it out that it was simply the double quotes character that was not valid. I replaced all the double quotes by typing it again. And then the code worked for me. Thought sharing this may help others.
6:49 pm - August 10th, 2009
There was a comment made by someone on this blog post recently who pointed out that when the code was copy/pasted to an editor – there was a problem with the double quotes. When the code was tested – they were getting “unknown error”. Then the developer fixed the pasted double quotes and all was well. However, to improve the quality of this post, I have re-written another .ashx file. I am now making a .ashx file called put_data_eh2.ashx. This file will post data to a SharePoint List called “testeh”. The “testeh” list will have a single field called “Title”. Also, I have included a test PDF form that has a Submit Button to post data to the list. This form has the Submit Button set as follows: Submit As is set to XML Data (XML). The Submit to URL is set to – “http://vhatamclintonvm/sites/dev/_layouts/CustomHttpHandlers/put_data_eh2.aspx” . This path assumes that you have a sub-directory in your LAYOUTS (12 Hive) directory called “CustomHttpHandlers”. You will obviously need to open this PDF form in Adobe Designer and modify the Submit to URL path to your specific path. Here is the .ashx file: Link to ASHX file. Here is the link to the PDF file: Link to PDF
8:48 pm - August 10th, 2009
I found there was one small ” I missed during the copy!
Form works now! (in adobe designer)
When I preview the form in adobe designer and submit, my form fills out my test list (WOOHOO!). When the form is standalone as in I just open the pdf in reader and hit submit, I get an “authorization error” from my .ashx file on the IIS. I’m missing something and will look over your supplied documents and compare them with my own but I’m imagining there is some kind of “reject” in IIS or sharepoint that doesn’t like the form coming from adobe reader.
Thanks so much for your patience!!!
12:13 pm - August 14th, 2009
When I try this example, and hit the Submit button I receive an error box from Adobe Reader that says “An erro occurred during the submit process, Unknown failure.” I have been thru the blog posts and just do not understand where the problem is. I am stuck any ideas?
1:05 pm - August 14th, 2009
PS Found out something very interesting, if I upload my Adobe Form to my SharePoint site and then open the Adobe Form from the SharePoint site, I can submit my data to the SharePoint list of that same site. When I try to run the same Adobe form from my desktop it fails. So it appears that something to do with security (I think) but its out of my level of understanding.
1:02 pm - August 27th, 2009
WOW! That works for me too, Trace! It has to be some permission thing that keeps the PDF form from talking to the .ashx on the server. This will be a workaround but I still would like to know what permission needs to be set so the doc doesn’t have to live in the library.
1:24 pm - November 11th, 2009
I got my http handler working after almost a year of trying to figure it out. Yeah, THank you for this post! Now I am wondering about submiting data to a sub site list.
I followed what I did for the first list, but kept running into an “Value does not fall within the expected range” error. After some trial and error, and process of elimination it seems to me that the problemis the name of the list. It is looking for a list on the root site.
I have tried somethings like SPList list=web.lists ["site/test"];
SPList list=web.lists ["site/test/"];
SPList list=web.lists ["site/test"];
SPList list=web.lists ["site/Lists/test"]; but I keep getting the same error. Maybe I am just brain fried but can you suggest anything else I could try?
9:03 am - January 20th, 2010
We are trying to do same kind of thing with PDF except that its a time off request. When someone fills out the form for a time off request, and then select the name of the manager fromt he dropdown it should send an email to that manager and then the manager picks Director and it goes to Director and then so on. Can this be done in the same way or is it something different
P.S. I have not started anythinga and i do not anything but this blog is a good start to start with
8:59 am - January 30th, 2010
I recommend that if you need to use the PDF form for the “time off” request, go ahead and try to get it to work with submitting the data to SharePoint as this post describes. This could be done for the initial request to be made. Then, once the initial request is made, forget about the Adobe form and use SharePoint to build a workflow that takes your Director (etc.) through the approval process. Once the initial data gets added to SharePoint via the Adobe form, you will have a workflow built that automatically sends an e-mail to the next approver in the process. The approver would then have a link in the e-mail that would take them to a custom .aspx page built within SharePoint that has fields for the approval. You would then have other workflows that continue the process as needed. If you don’t like the way that SharePoint works in this situation, you can do some research in Adobe’s “Process Management” server that will allow you to do all of this inside the Adobe form in a web-based environment. This is a very expensive alternative though.
5:00 pm - February 25th, 2010
Thank you so much for this post!!
I am having a couple of issues though and I don’t know where to go. First off, copied code and cleaned it per previous comments. Did the HelloHTTPHandler demo – it worked. I have my form, have the handler, have the list.
This is where I am pointing my form: https://servername/site/_layouts/specific_folder/put_data_in_sp_list.ashx
This is where my list is: https://servername/site/Lists/Advertising_Submissions/AllItems.aspx
I am getting unknown error but event viewer is hitting 2 errors – 111: Unable to apply folder redirection policy, initialization failed & 1085: The Group Policy client-side extension Folder Redirection failed to execute. Please look for any errors reported earlier by that extension.
I thought it was permissions at first but I am administrator so I should be able to post to the list .
I would greatly appreciate any help on this.
Thanks In Advance.