Enabling Custom Submission


Up to this point, we have focused on solutions that have taken advantage of the direct submission features of InfoPath. For some solutions, this won t be the correct implementation. InfoPath enables you to submit forms through either custom scripts or a generic HTTP POST.

Submitting with Custom Script

When an InfoPath document submits an XML document to a Web Service, the default behavior posts the contents of the individual nodes. This is a design feature that enables parameter-based field submission to the back-end Web Service. If the form designer wants to bypass this and submit the entire XML document, then he can enable a custom submit scripting routine by using the Submit options shown in Figure 4.23.


Figure 4.23: Enabling a custom submit function.

When enabled, XML submission occurs through the OnSubmitRequest function maintained as part of the application s solution file. For example, the script block shown in Listing 4.9 submits an entire XML request to a Web Service.

Listing 4.9: Submitting the entire InfoPath DOM to a Web Service.
start example
 try{   //Get a reference to the SendXMLNode secondary data source   var objSendXMLNode = XDocument.GetDOM("SendXMLNode");   objSendXMLNode.setProperty( "SelectionNamespaces",     'xmlns:s1="http://mycompany.schema.com/schema" ' +     'xmlns:s0="http://tempuri.org/" ' +     'xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/data  FormSolution"' );   //Remove any data from the SendXMLNode secondary data source   var objData = objSendXMLNode.selectSingleNode(   "/dfs:myFields/dfs:queryFields/s0:SendXMLNode/s0:theNode");   var objCurrentData = objData.selectNodes("@*  node()");   objCurrentData.removeAll();   //Clone the XDocument   var objClonedDocument = XDocument.DOM.documentElement.cloneNode(true );   objData.appendChild( objClonedDocument );   //Call the "Query" method of the secondary data source to send the data   XDocument.DataObjects("SendXMLNode").Query();   //Report the results of the submit   XDocument.UI.Alert(     objSendXMLNode.selectSingleNode( "/dfs:myFields/dfs:dataFields/s0:SendXMLNodeResponse/s0:SendXMLNodeResult").text );       eventObj.ReturnStatus = true;   }   catch(ex)   {       eventObj.ReturnStatus = false;   } 
end example
 

Another custom submission option is to use a custom SOAP message, shown in Listing 4.10. In this scenario, the form designer can define a custom message using the SOAP library and HTTP.

Listing 4.10: Defining a custom SOAP submission.
start example
 try   {     //Create a SOAP object     var objSOAPConnector = new ActiveXObject("MSOSOAP.HttpConnector30");   //Set the EndPointURL property to point to the Web Service   objSOAPConnector.Property("EndPointURL") = "http://server/WebService1/Submit.asmx";   //Set the SoapAction property to point to the Web Service Method. You  can find this URI   //in the WSDL file of the Web Service   objSOAPConnector.Property("SoapAction") = "http://tempuri.org/SendXMLNode";   objSOAPConnector.Connect();   //Begin construction of a SOAP message to send to the Web Service   objSOAPConnector.BeginMessage();   var objSOAPSerializer = new ActiveXObject("MSOSoap.SoapSerializer30");   objSOAPSerializer.Init( objSOAPConnector.InputStream );   objSOAPSerializer.startEnvelope();   objSOAPSerializer.startBody();   //Construct the structure that marks the method name and parameter  name we're sending   objSOAPSerializer.StartElement( "SendXMLNode", "http://tempuri.org/" );   objSOAPSerializer.StartElement( "theNode", "http://tempuri.org/" );   //Write out the XML of the document   objSOAPSerializer.WriteXml( XDocument.DOM.documentElement.xml );   //Finish each element   objSOAPSerializer.EndElement();   objSOAPSerializer.EndElement();   //Call EndMessage to complete the SOAP message and send it to the Web  Service Method.   //This results in the Web Service Method being called.   objSOAPSerializer.endBody();   objSOAPSerializer.endEnvelope();   objSOAPConnector.EndMessage();   //Use a SoapReader to read the response from the Web Service Method   var ResponseReader = new ActiveXObject("MSOSOAP.SoapReader30");   ResponseReader.Load( objSOAPConnector.OutputStream );   //If there was no error, return true   if (ResponseReader.Fault != null)   {     eventObj.ReturnStatus = false;     throw "Error submitting data: " + ResponseReader.Fault.xml;   }   eventObj.ReturnStatus = true; } catch (ex) {   XDocument.UI.Alert("Failed to submit document: " + ex.description); } 
end example
 

In this example, the custom SOAP message is instantiated using the ActiveXObject method of the XDocument object model.

Submitting with HTTP

Many times, an existing InfoPath application may become a part of an existing Web-based application. This includes posting to specific pages and then allowing the page to do something with the data. When InfoPath posts to an HTTP address, the form data is actually contained as part of the binary stream. This means that as part of a post request, Web developers cannot access it within a Web page using either the form or variables collection. In order to access the posted data, developers use the readbinary method of the request object to retrieve the byte array that contains the data. Once retrieved, this data can be converted to a string and then processed on the Web page.

ASP.NET provides a low-level request/response API that enables developers to use the .NET Framework classes to service incoming HTTP requests . This is provided in the System.Web.IHTTPHandler interface and implements the Process Request method. These handler types are useful when the services provided by the high-level page framework abstraction are not required for processing an HTTP request.

Each incoming HTTP request received by ASP.NET is ultimately processed by a specific instance of a class that implements IHTTPHandler . The IHTTPHandlerFactory provides the infrastructure that handles the actual resolution of URL requests to IHTTPHandler instances. In addition to the default IHTTPHandlerFactory classes provided by ASP.NET, developers can create and register factories to support their own request resolution and activation scenarios.

Using InfoPath, you can have a form provide a post request using HTTP by editing the form properties and selecting HTTP with the URL of the page that you want to submit the request to, as shown in Figure 4.24.


Figure 4.24: Defining an HTTP request.

Within the page load event, we could add the code in Listing 4.11, which shows the submitted response of the Interview Feedback form in an ASP.NET Web Form DataGrid .

Listing 4.11: Retrieving the interview information to an ASP.NET DataGrid.
start example
 Dim binread As Byte()     Dim bytecount As Integer     bytecount = Request.TotalBytes     binread = Request.BinaryRead(bytecount)     'Converts the binary data to a string.     Dim i As Integer     Dim temp As Byte()     Dim spost As String     For i = 0 To (Request.TotalBytes - 1)       spost = spost & Chr(binread(i))     Next     'Response.Write(spost)     If spost = "" Then       Page.Response.Write("Nothing to show")     Else       Dim stream As System.IO.StringReader       Dim reader As System.Xml.XmlTextReader = Nothing       stream = New System.IO.StringReader(spost)       Dim ds As New System.Data.DataSet       ds.ReadXml(stream)       DataGrid1.DataSource = ds       DataGrid1.DataBind()     End If 
end example
 

This code grabs the binary stream of data and reads the request. This request data is then bound to the DataGrid object and displayed using an ASP.NET page.




Programming Microsoft Infopath. A Developers Guide
Programming Microsoft Infopath: A Developers Guide
ISBN: 1584504536
EAN: 2147483647
Year: 2006
Pages: 111
Authors: Thom Robbins

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net