TechEd Source Code

Some people were using digital cameras to capture the source code from our "InfoPath: Developing Forms with Managed Code" sessions, but we want to make it easier than that!

So here's the code Ned Friend used in the TechEd Europe version of the presentation (David Gerhardt used similar code in his USA version of the talk in Orlando):

DISCLAIMER: This code is designed to be short and sweet for demo purposes only. IT IS NOT BEST PRACTICES NOR READY FOR PRODUCTION.

using

System;

using

Microsoft.Office.Interop.InfoPath.SemiTrust;

// Add .NET reference: System.Xml

using

System.Xml;

using

System.Xml.Xsl;

using

System.Security.Cryptography;

using

System.IO;

// Add COM reference: Microsoft Word 11.0 Object Library

using

Word = Microsoft.Office.Interop.Word;

// Office integration attribute. Identifies the startup class for the form. Do not

// modify.

[assembly: System.ComponentModel.DescriptionAttribute(

"InfoPathStartupClass, Version=1.0, Class=StatusReport.StatusReport")]

namespace

StatusReport

{

// The namespace prefixes defined in this attribute must remain synchronized with

// those in the form definition file (.xsf).

[InfoPathNamespace(

"xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xdUtil="http://schemas.microsoft.com/office/infopath/2003/xslt/Util" xmlns:xdXDocument="http://schemas.microsoft.com/office/infopath/2003/xslt/xDocument" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xdMath="http://schemas.microsoft.com/office/infopath/2003/xslt/Math" xmlns:xsf="http://schemas.microsoft.com/office/infopath/2003/solutionDefinition" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2005-05-24T18:10:14" xmlns:xdDate="http://schemas.microsoft.com/office/infopath/2003/xslt/Date" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"")]

public class StatusReport

{

private XDocument thisXDocument;

private Application thisApplication;

// For encryption/decryption

private Rijndael key = new RijndaelManaged();

public void _Startup(Application app, XDocument doc)

{

thisXDocument = doc;

thisApplication = app;

// You can add additional initialization code here.

}

public void _Shutdown()

{

}

// The following function handler is created by Microsoft Office InfoPath. Do not

// modify the type or number of arguments.

[InfoPathEventHandler(EventType = InfoPathEventType.OnLoad)]

public void OnLoad(DocReturnEvent e)

{

// Set the username

IXMLDOMNode userName =

thisXDocument.DOM.selectSingleNode(

"/my:status/my:name");

if (userName.text == String.Empty)

{

userName.text = Environment.UserName;

}

// Load key information

IXMLDOMNode keyNode = thisXDocument.DOM.selectSingleNode(

"/my:status/my:key");

IXMLDOMNode ivNode = thisXDocument.DOM.selectSingleNode(

"/my:status/my:iv");

byte[] keyBytes = Convert.FromBase64String(keyNode.text);

byte[] ivBytes = Convert.FromBase64String(ivNode.text);

// Decrypting the project name

MemoryStream ms =

new MemoryStream();

CryptoStream csRijndael =

new CryptoStream(ms, key.CreateDecryptor(keyBytes, ivBytes), CryptoStreamMode.Write);

IXMLDOMNode projectNode =

thisXDocument.DOM.selectSingleNode(

"/my:status/my:project/my:name");

byte[] projectBytes = Convert.FromBase64String(projectNode.text);

csRijndael.Write(projectBytes, 0, (

int)projectBytes.Length);

csRijndael.FlushFinalBlock();

string projectName =

System.Text.Encoding.Unicode.GetString(ms.GetBuffer(), 0, (

int)ms.Length);

projectNode.text = projectName;

}

// The following function handler is created by Microsoft Office InfoPath. Do not

// modify the type or number of arguments.

[InfoPathEventHandler(MatchPath =

"/my:status/my:date", EventType = InfoPathEventType.OnValidate)]

public void date_OnValidate(DataDOMEvent e)

{

// Custom data validation because InfoPath does not have functions for date arithmetic

if (e.Operation == "Insert")

{

try

{

DateTime date = DateTime.Parse(e.NewValue.ToString());

if (date.CompareTo(DateTime.Today.AddDays(5)) > 0)

{

e.ReportError(e.Site,

"Date cannot be more than 5 days away.",

false, null, 1, "modal");

}

}

catch (FormatException)

{

// Incorrectly formatted dates are handled automatically by InfoPath.

}

}

}

// The following function handler is created by Microsoft Office InfoPath. Do not

// modify the type or number of arguments.

[InfoPathEventHandler(EventType = InfoPathEventType.OnSubmitRequest)]

public void OnSubmitRequest(DocReturnEvent e)

{

// If Online, submit using data adapter

if (thisApplication.MachineOnlineState == XdMachineOnlineState.xdOnline)

{

WebServiceAdapter2 webServiceAdapter =

(WebServiceAdapter2)thisXDocument.DataAdapters[

"Submit"];

webServiceAdapter.Submit();

}

// If Offline, save to cache

else

{

XmlDocument xmlDoc =

new XmlDocument();

string now = DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss.ff");

xmlDoc.PreserveWhitespace =

true;

xmlDoc.LoadXml(thisXDocument.DOM.xml);

xmlDoc.Save(

"C:\TechEd2005\Submit\Form " + now + ".xml");

}

e.ReturnStatus =

true;

}

// The following function handler is created by Microsoft Office InfoPath. Do not

// modify the type or number of arguments.

[InfoPathEventHandler(EventType = InfoPathEventType.OnSaveRequest)]

public void OnSaveRequest(SaveEvent e)

{

// Set up encryption streams

MemoryStream ms =

new MemoryStream();

CryptoStream csBase64 =

new CryptoStream(ms, new ToBase64Transform(), CryptoStreamMode.Write);

CryptoStream csRijndael =

new CryptoStream(csBase64, key.CreateEncryptor(), CryptoStreamMode.Write);

// Encrypt project name

IXMLDOMNode projectNode =

thisXDocument.DOM.selectSingleNode(

"/my:status/my:project/my:name");

byte[] projectBytes =

System.Text.Encoding.Unicode.GetBytes(projectNode.text);

csRijndael.Write(projectBytes, 0, (

int)projectBytes.Length);

csRijndael.FlushFinalBlock();

string projectEncrypted =

System.Text.Encoding.ASCII.GetString(ms.GetBuffer(), 0, (

int)ms.Length);

// Save key information

IXMLDOMNode keyNode = thisXDocument.DOM.selectSingleNode(

"/my:status/my:key");

IXMLDOMNode ivNode = thisXDocument.DOM.selectSingleNode(

"/my:status/my:iv");

keyNode.text = Convert.ToBase64String(key.Key);

ivNode.text = Convert.ToBase64String(key.IV);

// Save encrypted project name, then decrypt in view

string projectOriginal = projectNode.text;

projectNode.text = projectEncrypted;

e.IsCancelled = e.PerformSaveOperation();

projectNode.text = projectOriginal;

thisXDocument.SetDirty(

false);

e.ReturnStatus =

true;

}

// The following function handler is created by Microsoft Office InfoPath. Do not

// modify the type or number of arguments.

[InfoPathEventHandler(MatchPath =

"ButtonGenerate", EventType = InfoPathEventType.OnClick)]

public void ButtonGenerate_OnClick(DocActionEvent e)

{

// This button converts the XML Form to a Word Document

// Load the XSLT file from resources

IXMLDOMDocument domDocument = thisXDocument.CreateDOM();

domDocument.load(

"StatusReport.xsl");

XmlDocument xsltDocument =

new XmlDocument();

xsltDocument.LoadXml(domDocument.xml);

// Load the XML DOM into System.Xml

XmlDocument infoPathDocument =

new XmlDocument();

infoPathDocument.LoadXml(thisXDocument.DOM.xml);

// Apply the XSLT to the XML DOM

XslCompiledTransform xslt =

new XslCompiledTransform();

xslt.Load(xsltDocument);

XmlDocument outputDocument =

new XmlDocument();

System.Xml.XPath.XPathNavigator outputNavigator = outputDocument.CreateNavigator();

using (XmlWriter writer = outputNavigator.AppendChild())

{

xslt.Transform(infoPathDocument, writer);

}

// Instantiate Word with the new document

object missing = System.Reflection.Missing.Value;

Word.Application wordApplication =

new Word.ApplicationClass();

Word.Document oDoc =

new Word.DocumentClass();

oDoc = wordApplication.Documents.Add(

ref missing, ref missing, ref missing, ref missing);

wordApplication.Selection.Range.InsertXML(outputDocument.OuterXml,

ref missing);

wordApplication.Visible =

true;

}

}

}