InfoPath (+K2): The form has been closed

InfoPath forms services is widely discussed product, you either love it or hate it. You mostly hate it because you would want more from the product then you can get, you’re then simply running into the boundaries of InfoPath. IMHO this is a limitation of working with out of the box products.

K2 BlackPearl is able to integrate really well with InfoPath and is able to use InfoPath Forms Server so you don’t need the full client on all the client machines. However, forms services add a few extra limitations.

When you’re using K2 and InfoPath you can finish your K2 tasks by submitting the forms, this kicks of a web service call which helps the process move along and execute your K2 action. After it has been submit, the form will be closed, this is something the K2 integration adds (you can change it, but what’s the point). The user is then prompted with the following screen:

formclosed

Some people think this is an error, because sometimes when forms server isn’t able to open the form correctly, this is shown. In this case it’s a perfectly valid message because infopath is configured like this.

For the end user this isn’t very user friendly and some will press the back button or close the window. The best solution is to navigate back to the K2 tasklist so the end user can pick up the next task.

Getting InfoPath to go back

The ones out there that have experience calling the Forms Server url from your code know that there is a Source querystring parameter. And if your using the normal sharepoint list actions you can alter those.

To fix this in K2, you need know how K2 opens a InfoPath Client Event. And here’s a diagram of that:

OpenTaskFlow

The important part is in the OpenInfoPathTask.aspx, so here’s a diagram of that:

OpenInfoPathTask

The OpenInfoPathTask.aspx gets a lot of querystring parameters which are defined in the Event Item code of the InfoPath Client Event. Because the OpenInfoPathTask.aspx is in between the tasklist and the InfoPath forms services page, you do not have control over the parameters that are passed to the /_layouts/FormServer.aspx query. And, it doesn’t forward/copy the Source parameter.

URL rewrite, the solution

The solution to this was hard to find, but a college (Thijs Kroesbergen) mentioned something called URL Rewriting. It’s pretty weird that I didn’t think of it because I have used it on several sites before. Even this blog uses it.

URL rewriting is available in IIS7 but not in IIS5 or IIS6. There are 3rd party IIS ISAPI filters, we choose for the Ionic’s ISAPI Rewrite Filter which is available from Codeplex.com. Although the configuration parameters might seem the same as Apache’s mod_rewrite, they are not! Read the readme file for the real stuff, it’s a long read but is needed.

Install and Configure the ISAPI filter

To install the ISAPI filter:

  • Place the IsapiRewrite4.dll file in the c:\windows\system32\inetsrv\IIRF
  • Add an IsapiRewrite4.ini file to the same directory
  • Add read permissions for IIS_WPG to the DLL and INI file.
  • If you have logging in the INI file, add that directory and provide ‘Everybody’ with full control (hey, make it easy on yourself J)
  • Go into Internet Information manager (winkey + R; type ‘inetmgr’)
  • Go to the properties of the web site where the InfoPath forms server is hosted (so your sharepoint site)
  • Go to the ISAPI tab
  • Add the ISAPI filter

Now the INI file contains the real ‘magic’. Here’s what we used:

# IsapiRewrite4.ini
#
# ini file for the ISAPI rewriter.
#
# Tue, 11 Jul 2006  01:49
#

RewriteLog  c:\temp\iirfLog.txt

RewriteLogLevel 3

#
# This ini file illustrates the use of a redirect rule.
# Any incoming URL that starts with an uppercase W
# will be redirected to the specified server.

RewriteCond %{URL}   ^/_layouts/FormServer.aspx.*$
RewriteRule ^(.*)$     $1&Source=http://gpr:1000/

This simply adds the Source parameter to the querystring. You will NOT see this in the browser address bar, but for IIS it’s there!

The RewriteLogLevel 3 defines a loglevel, and the RewriteLog provides the location, remember to set permissions and disable this in production.

The RewriteCond is a filter to apply the next line or not, so this checks if the “^/_layouts/FormServer.aspx.*$ matches the variable ‘URL’ which is the URL, but for forms services this is without ‘http://domain.tld’.

The RewriteRule then matches the hole query and adds &Source=http://gpr:1000/ to the string. The ^(.*)$ marks what’s set in $1 (everything). These are all common things within regular expressions, hard to learn but worth it.

Because the Source Parameter is now successfully added, the form will close and move back to a defined page (in this case, http://gpr:1000) is where the tasklist is. Please remember that the Source parameter should be filled with a URL within the SAME site collection.

And that’s it. You are now able to specify the Source parameter to the sites, it’s not dynamic (i know) but you can also redirect to some other page which handles other stuff, like close the window, just remember that this page needs to be in the same site collection!