Trick #1: Programmatically dropping InfoPath forms into a forms library
Trick 2, Trick 3
Business Case:
I've come so notice that SharePoint isn't the easiest platform for end users to learn. When the IT department decides they want to "virtualize" their processes and will leverage InfoPath to do so, end users quickly reach for their panic buttons. The business case in my mind for programmatically deploying an InfoPath form is that sometimes even the "New" button is too complicated for users. Dropping a new form on behalf of the user, and saving them a few clicks can save on YOUR support budget.
Take an expense report, for example. On an HR site, you may have a link on the quick launch for "Expense Reports". This takes the user to a form library. They somehow at this point need to know to click the "New" button – and possibly the New dropdown to choose between various content types. This in turn will lead to opening of the InfoPath thick client – which they probably don't have installed. If form server is configured, they should've known to upload the XML data file, rather than click New, and then click Edit In Browser. Funny how them end users struggle with this? J
Alternative – On the HR site, create a link called "Submit an Expense Report". This, when clicked, programmatically drops an empty form in a library, and automatically redirects the user to the URL for browser based editing. They fill out the form and clicks submit, and are redirected back to the HR site – never even seeing the underlying form library. Completely brainless.
Walkthrough:
With all that said, here are the steps to programmatically drop an InfoPath form in a form library:
1. Create a form, save the form, and then check Preview – Form:
2. Fill out the form, and then click Save. This will save the data as an XML file.
3. Add that XML file to a Visual Studio Project.
4. Set the compile action to be Embedded Resource (right click – properties):
5. Optional – If using Forms Server, edit the XML file's name and URL tag to point to the template loaded in Forms Server:
(to get the name, go to Central Administration, Application Settings, manage form templates. Then, view the properties on the form and look for the "Form ID" property.)
6. Use the following code to deploy the form:
using System;
using System.IO;
using System.Reflection;
using Microsoft.SharePoint;
public class Class1
{
public void foo()
{
Stream stream =
Assembly.GetExecutingAssembly()
.GetManifestResourceStream(@"AssemblyName.FormName.xml");
byte[] content = new byte[stream.Length];
// Read the file from the stream into the byte array
stream.Read(content, 0, (int)stream.Length);
stream.Close();
using (SPSite mySiteCollection = new SPSite("http://foobar.com"))
{
using (SPWeb myWeb = mySiteCollection.RootWeb)
{
string libraryName = "HR Forms";
// Get the folder that should store the document
SPFolder root = myWeb.Folders[libraryName];
string fileNameOnceInLibrary = "UniqueFileName";
// Add the file to the Files collection and commit to database
SPFile file = root.Files.Add(
root.Url + "/" + fileNameOnceInLibrary, content, true);
root.Update();
}
}
// Send user to edit/submit new form via Form Server
Page.Response.Redirect(
"/HR/_layouts/formserver.aspx?XmlLocation=" +
"/HR%20Forms/" + fileNameOnceInLibrary + ".xml&OpenIn=Browser");
}
}
This code opens a stream on the embedded resource and loads that stream into a byte array. Then the SharePoint web and folder (form library) are opened and a new document is added to the form library using the byte array as its content source. Lastly the user is redirected to Form Server to edit/submit the form, and after they have submitted the form, logic in the form can send them back to the HR landing page – thus removing any need to know anything about SharePoint!
Trick #2 and #3 will be out it a couple days…
Phil
(ps – if you know how to load form server, rather than the thick client, when a user clicks the New button, let me know J)