Rich Text and Web Services
Applies to: InfoPath 2010 | InfoPath Forms Services | Office 2010 | SharePoint Server 2010 | Visual Studio | Visual Studio Tools for Microsoft Office
Microsoft InfoPath 2010 supports binding a Rich Text Box control in a form to an XML element that is received from a Web service, and submitting data from a rich text box control to an XML element through a Web service. The element must adhere to the Extensible HyperText Markup Language (XHTML) format. For example, the schema for an element named MyRichTextElement that contains rich text would have the following XML schema definition:
<xsd:element name="MyRichTextElement">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:any namespace="http://www.w3.org/1999/xhtml" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Before a Rich Text Box control can be bound with the XHTML element, the element should be wrapped with a wrapper node; this wrapper node can belong to any arbitrary namespace. The wrapper node can look like this:
<xhtmlNode xmlns="http:// someNamespace">
<div xmlns="http://www.w3.org/1999/xhtml">Your rich text here</div>
</xhtmlNode>
This topic outlines the process of creating a Web service that can send and receive XHTML, and how to use InfoPath to bind to the Web service parameters. This topic does not provide detailed instructions on how to create such a Web service. It is assumed that you already have some familiarity with working with Web services.
How to Design a Web Service to Receive and Send XHTML
The example Web service stores the XHTML data that it sends and receives in an XML file on the server. This file that is named out.xml, acts as a data source that stores the XHTML data. There are two Web methods that will be exposed to allow a client application to interface with the XHTML data source: getXhtml and setXhtml. The getXhtml Web Service method returns an XmlNode that contains the XHTML that can be bound to an InfoPath rich text box control. The setXhtml Web Service method accepts an XmlNode as the data to store in the out.xml file.
Note
These Web methods require using statements that reference the System.IO and System.Xml namespaces.
The getXhtml Web Service method attempts to load the XML data to be returned from the out.xml file in the Data folder on drive C. If it fails, because the file is not found, or does not contain valid XML, the method will return an empty DIV HTML element that references the XHTML namespace.
[WebMethod]
public XmlNode getXhtml()
{
// This is the returned XmlDocument upon Query from InfoPath
XmlDocument document = new XmlDocument();
// Create a wrapping node with the name of the rich text field.
// The "http://someNameSpace" can be any arbitrary namespace
XmlNode richNode = document.CreateNode
(XmlNodeType.Element, "MyRichTextElement", "http://someNameSpace");
// Temporary XmlDocument
XmlDocument tempDocument = new XmlDocument();
try
{
// Read the saved rich text data from the local machine
tempDocument.Load(@"c:\Data\out.xml");
}
catch (XmlException)
{
// If the file does not exist or content is not valid XML
tempDocument.LoadXml("<div xmlns=\"http://www.w3.org/1999/xhtml\"></div>");
}
// Add the file content to the xml
richNode.AppendChild
(document.ImportNode(tempDocument.DocumentElement, true));
return richNode;
}
The setXhtml Web Service method accepts XHTML from a Rich Text Box control on an InfoPath form. Because Web services do not support a node list, when a rich text field that contains multiple lines is sent to a Web service, the Web service only accepts the first line and ignores the rest.
The sample setXhtml method assumes that it will receive a top-level XML node, which in most cases will be wrapped in a DIV element. If the XML received does not contain a wrapping element, for example when text within the Rich Text Box control has no formatting, this method will detect this by checking whether the NodeType property indicates that the XML passed in is a text node. If the XML is a text node, the method creates a DIV element and copies the text node contents to the DIV so that the DIV contains a text node child with the text that was sent to the Web service. The XML received by this method is written to the out.xml file in the Data folder on the drive C.
Note
The sample setXhtml method was written to accept XHTML data of any size. In actual practice, you should always check to see how much data is being submitted and set an upper limit for how much data that can be submitted.
[WebMethod]
public void setXhtml(XmlNode xn)
{
XmlDocument document = new XmlDocument();
if (xn == null)
{
// If nothing was submitted or the rich text field is empty,
// create a DIV that references the XHTML namespace
XmlElement div = document.CreateElement("div", "http://www.w3.org/1999/xhtml");
// Copy the node to our own XmlDocument
document.AppendChild(div);
}
if (xn.NodeType == XmlNodeType.Text)
{
// If plain text is passed in, wrap it in a DIV
// that references the XHTML namespace
XmlElement div = document.CreateElement("div", "http://www.w3.org/1999/xhtml");
// Copy the text to the DIV.
div.AppendChild(document.ImportNode(xn, true));
// Copy the node to our own XmlDocument
document.AppendChild(div);
}
else
{
// Copy the node to our own XmlDocument
document.AppendChild(document.ImportNode(xn, true));
}
// Save the file to the local machine
document.Save(@"c:\Data\out.xml");
}
How to Create an InfoPath Form That Exchanges Data with the Sample Web Service
Perform the following steps to create a form to test the sample Web service.
To create a form that connects to the sample Web service
Open the InfoPath form designer.
On the New tab, double-click Web Service under Advanced Form Templates.
In the Data Connection Wizard dialog box, select Receive data, and then click Next.
Type the address of the Web service that contains the sample Web service methods, and then click Next.
For the receive method, select getXhtml as the operation, and then click Next.
The getXHTML Web service method takes no parameters, so click Next.
Click Finish.
On the Data tab, in the Submit Actions group click To Other Locations, and then click Web Service to use the same Web service to the submit data.
Type the address of the Web service that contains the sample Web service methods, and then click Next.
For the submit method, select setXhtml as the operation, and then click Next.
Click Modify, expand the dataFields folder, expand thes0:getXhtmlResponse folder, expand the getXhtmlResult folder, select the MyRichTextElement element, and then click Next.
Click Finish.
In the Fields task pane, expand the dataFields folder.
Expand the s0:getXhtmlResponse and getXhtmlResult folders, and then drag the MyRichTextElement element onto the form. InfoPath will recognize that the MyRichTextElement element is an XHTML element and will use a rich text box control to bind to it.
Save or publish the form.
To test the form, open the form, enter some rich text content such as pictures, tables, and formatted text. Click Submit on the ribbon to store the rich text content in the out.xml file on the server. Click Query on the View tab, and then click the Run Query button on the form. The Rich Text Box control should display the XHTML content from the out.xml file. If the rich text field contains multiple lines, the Web service will only accept the first line and ignore the rest.