SharePoint site with InfoPath forms and Random session lost issue

We were able to fix a sticky issue which was bugging us since a long time. Its a sporadic issue and its always interesting to debug issues like these.

Issue details: This is in reference to SharePoint portal site which uses InfoPath Forms extensively which was extended into multiple zones (intranet, extranet) with dual authentication (AD and LDAP with MFA/FBA). The issue with the site was that it was losing the session randomly while the user is actively working on it. The random time period could be anywhere from 8 mins to 20mins or more.

Debugging the issue: We started facing this issue in our (staging/no-harm) environment and later we realized it wasn’t isolated to a specific environment as this was reproducible in our QA, UAT etc environments too. Changing or increasing the session timeout value was certainly not having any kind of effect on the random timeout issue. That was ruled out of the picture. I started looking into SharePoint logs, IIS logs and Application specific event logs, still hitting the wall.

With the infrastructure we have one hits the SharePoint site through a multi-factored authenticated (MFA) site which is basically a single point of entry for external partners. This MFA site authenticates using SiteMinder/LDAP. The extranet forms based authenticated (FBA) based SharePoint site picks up the user context from this site without prompting the user to log in again.  The next step was pushing this issue to the MFA/Application-security team to verify if all is well from their side.  Yes, everything remains the same and fine on their side.

We have been using Fiddler/HTTPWatcher to track the http headers exchanged while trying to reproduce the session lost issue. After tracking down the HTTP headers while reproducing the session lost I found that the ASP.NET_SessionId cookie which was supposed to be sent in the header is  not being sent at that moment and thus session is lost.

Below is a small useful excerpt from a blog link:

How a web application uses cookies to maintain session state is simple: the application framework simply associates all the runtime state of the application with the ID (i.e. SessionID) and makes sure to send that ID with a Set-Cookie on the initial HTTP response, and whenever the web browser makes a subsquent request to the application’s URL namespace, the application framework inspects the cookie header for an ID and if it is found, look up all of the associated runtime state and continue processing the web application with that state. Good application frameworks would also control the time period of validity for this runtime state via something like Session

But now the question arises about what and why this is happening? Why does the browser stop sending the ASP.NET_SessionId cookie randomly?

One thing that I noticed is that there are multiple cookies that are maintained and the number of cookies are increasing for each page refresh or access. On close observation we narrowed it down that on page access that has an XMLFormView control which contains the InfoPath form is adding 2 cookies which look something like below:

2877de91-2fc1-48bd-b134-7e5480751aa1_sel    Sent        /    test..com    (Session)

2d12188c-1f35-427c-b741-634acde50a8e_pb    Sent    0    /    test.com    (Session)

I couldn’t find any good documentation/links on how InfoPath Forms Services use cookies especially the above ones. However, the _sel and _pb represents the selection and postback cookies.

As the number of cookies are increasing and as it exceeds the browser limitation of max 20 cookies per domain the ASP.NET_SessionId is dropped and thus the session is lost.  Here is the copy one of the lines from Microsoft KB Article:

If a Web application uses more than 19 custom cookies, ASP session state may be lost.

In order to conclude this I wrote a quick and dirty (my favorite) java script solution to remove the InfoPath form cookies that are not used or empty and retain only the latest 2 cookies. With this script plugged into the master page the session lost issue never happened again.

I uploaded the script to SkyDrive. Here is the link to the folder and you will see a file named: CookieCleanupScript.txt

https://skydrive.live.com/redir?resid=52790689DEA81341!6040

Advertisements

Remove/Hide/Customize InfoPath Forms Tool Tip

On your sharepoint front end servers, go to the following location
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\INC\

Make a backup copy of ifsmain.css.
Then edit the ifsmain.css file as follows:
Search (ctrl + F) for the css class “.errorDiv”, it is something like below:

To hide/remove tool tip:
.errorDiv
{
z-index:100;position:absolute;top:0px;left:0px;display:none;width:300px;padding:2px 3px; border:1px solid  #B22828;background:#FFFED7;color:#B22828;

font-family:Verdana; font-size:x-small; text-decoration:none;font-weight:normal;

}

Modify the above script by adding “!important” just beside display:none. The modified .errorDiv is as follows:

.errorDiv
{
z-index:100;position:absolute;top:0px;left:0px;display:none !important;width:300px;padding:2px 3px;
border:1px solid #B22828;background:#FFFED7;color:#B22828;

font-family:Verdana;
font-size:x-small;
text-decoration:none;font-weight:normal;
}

You can further customize the tool tips as per your needs if that is your requirement instead of hiding it.

The only drawback with this approach is that it will affect the complete server farm. Thus, all the infopath forms on all the sites will be affected with this change.

Update (12/1/09):

Good news is that we were able to figure out how to customize the tool tip specific to a site or page level thus avoiding the drawback mentioned in the above method of implementation. Using a content editor web part you can insert the required Html (also CSS) into a page. Leveraging this technique we were able to add a content editor web part (CEWP) to our custom application page which hosts the infopath form. This content editor web part envelopes the CSS changes required to the tool tip. Below is the CEWP content we added to our page:

<WebPartPages:ContentEditorWebPart runat=”server” __MarkupType=”xmlmarkup” WebPart=”true” __WebPartId=”{87D17157-ECD0-49D6-9906-2DAA4C400992}”>
<WebPart xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns:xsd=”http://www.w3.org/2001/XMLSchema&#8221; xmlns=”http://schemas.microsoft.com/WebPart/v2″&gt;
<Title>Content Editor Web Part</Title>
<FrameType>None</FrameType>
<Description>Use for formatted text, tables, and images.</Description>
<IsIncluded>true</IsIncluded>
<PartOrder>1</PartOrder>
<FrameState>Normal</FrameState>
<Height />
<Width />
<AllowRemove>true</AllowRemove>
<AllowZoneChange>true</AllowZoneChange>
<AllowMinimize>true</AllowMinimize>
<AllowConnect>true</AllowConnect>
<AllowEdit>true</AllowEdit>
<AllowHide>true</AllowHide>
<IsVisible>true</IsVisible>
<DetailLink />
<HelpLink />
<HelpMode>Modeless</HelpMode>
<Dir>Default</Dir>
<PartImageSmall />
<MissingAssembly>Cannot import this Web Part.</MissingAssembly>
<PartImageLarge>/_layouts/images/mscontl.gif</PartImageLarge>
<IsIncludedFilter />
<ExportControlledProperties>true</ExportControlledProperties>
<ConnectionID>00000000-0000-0000-0000-000000000000</ConnectionID>
<ID>g_87d17157_ecd0_49d6_9906_2daa4c400992</ID>
<ContentLink xmlns=”http://schemas.microsoft.com/WebPart/v2/ContentEditor&#8221; />
<Content xmlns=”http://schemas.microsoft.com/WebPart/v2/ContentEditor”>&lt;![CDATA[<style type=”text/css”>
.errorDiv
{
z-index:100;position:absolute;top:0px;left:0px;display:none;width:200px;padding:2px 3px;border:1px solid #B22828;background:#FFFED7;color:#B22828;font-family:Arial;
font-size:xx-small;
text-decoration:none;font-weight:normal;
}
.errorDivClickable
{
z-index:100;position:absolute;top:0px;left:0px;display:none;width:300px;padding:2px 3px;
border:1px solid #B22828;background:#FFFED7;color:#B22828;
font-family:Arial;
font-size:xx-small;
cursor:pointer;cursor:hand;font-weight:normal;
}
</style>]]></Content>
<PartStorage xmlns=”http://schemas.microsoft.com/WebPart/v2/ContentEditor&#8221; />
</WebPart>
</WebPartPages:ContentEditorWebPart>

InfoPath Form HyperLink Open in Same Window

Problem: The hyperlink control in a browser enabled infopath form opens up in a new window. This might not be a good thing as a usability perspective. It might work for some and might not for many. This post is for those ‘many’.

Solution:

Note: This solution is valid only for the forms with managed code behind.

The solution I have is very trivial. Just drop a button on the form, stylize it to change its look and feel like an hyperlink. Then on the button click event of the form, just redirect the page to the URL you wanted to. There is a catch or two here.

A) On the click event, you make sure that the existing web request is completed before redirecting to your desierd page. So the code should look something like this:

HttpContext.Current.Response.Redirect(“http://somesite.com/page.html&#8221;,  false);

Passing the second parameter as ‘false’ we are ensuring that the current web request is completed and then redirected.

B) To make the button to be a hyperlink you need to do the following:

Right click the button select ‘borders and shading’, select None under presets. Then under the ‘shading’ tab select the radio button for ‘No color’. Then change the font color to blue(hyperlinks are usually blue) and make it underlined.

After doign all this there is still one thing that remains, i.e the mouse turning into a hand on hover over the button. To accomplish this, from file menu, select save as source files. From the source files, edit the view1.xls file, to set the style to cursor:pointer for the button element. Then open up the manifest.xsf in design mode. You will see the button as an hyper link including mouse hover.

Update (09/03/09):

There is a kind of caveat for the above implementation. Whenever the Response.Redirect is done, the new page from code behind of the InfoPath Form, eventhough the page is redirected, the URL in the browser address bar remains the same. It behaves as the Server.Transfer method.

To fix this anomaly the workaround is redirect to an intermediary page which in turn redirects to the actual page you want to redirect. The intermediary page could be a simple page with java script redirect method.

InfoPath Managed Form Templates Deployment Tool for SharePoint

This tool is an effort towards helping all those who are working on InfoPath Forms with SharePoint. It helps to upload/install, re-install, upgrade a form template with just a click of the button. The tool also can help in generating a script/batch file so that you can run it manually later on. Also, the tool has ‘Feature Management’ addon, using which you can see a list of activated and deactivated features using a filter if needed. It also provides the ability to activate, deactivate and uninstall a feature.
You can get the tool and read more about it at http://www.codeplex.com/InfoPathFormsInstall
Please let me know of the bugs and enhancements if anyone uses it.
Below is the screen shot of the tool:

InfoPath Form Template Deployer

InfoPath Form Template Deployer

InfoPath Managed Form Templates – upload status stuck or remains forever in ‘installing’ or ‘deleting’ state

The standard approach to upload any managed form template is to go to central admin and select ‘Manage form templates’ and upload the form template. The process isn’t complete, the ‘status’ column should show as ‘Ready’, only then we can activate it to a site collection. Once we upload the status shows as ‘Installing’ and once the SharePoint timer job kicks in it completes the installation behind the scenes and the status is changed to ‘Ready’. The same happens with ‘Deleting’ which completes only when the timer job completes it.

This whole process is long and gruesome if we have to repeat for many forms so I posted some time back on how to use stsadm.exe script to upload/delete/update the managed form templates. That works great.

But it didn’t work for few days back, once the upload is done, the status remained as ‘Installing’ forever . I ran the ‘stsadm.exe -o execadmsvcjobs’ command which forces the timer jobs to complete. Even that didn’t help. Just to get rid of the form, I opted to remove the template which changed the status column to ‘Deleting’ which remained like that forever.

I then started looking out for the reasons behind this weird behavior, and I see that either there should be a problem with the form template itself or the server farm. I ruled out the first reason because, I was not able to complete the upload process for none of the forms.

So, the problem is with the server farm, in which we have a single application server, a single front end web server and a database server. For the upload process to complete, the form template has to be propagated properly to all the servers in the farm. For this propagation, there are 2 important services which should be ON and working, they are:
SPTimerV3 and
SPAdmin
Run the following command to make sure those services are up and running on the servers in the farm:

  • net start SPTimerV3
  • net start SPAdmin

I checked the both on App and Front end servers and both those services were up and running. I was taken aback because this leads me to no where but back to the problem. After some time I ran those commands on the Database server too and I found that the SPAdmin service was not started on it. Once it is started all my form templates worked like a magic.

So just make sure the above services are up and running on not just the application and front end web servers but also on the database servers. Here is a good post which talks about the same.

UPDATE: I completely missed writing about how to undo the stalled status after uploading the form. Please follow the below instructions as per the post I mentioned above:

From Central Administration, go to the Operations page, under the Global configuration group, click on Timer Job Status.  On that page, look for timer jobs that have the name in the following formatting.  If you filename is FOO.xsn, it will look like:
Windows SharePoint Services Solution Deployment for “form-FOO.wsp”

See if there was a failure.  If so, go back a page, and go to Timer Job Definitions.  Drill down in the timer job definition that you care about and you can perform the following:

>> For the case of status stuck on “Uploading”:
1.       Try to restart the job if that is available.
2.       If restart is not available, delete the job, then attempt to upgrade again.

>> For the case of status stuck on “Upgrading”:
1.       Try to restart the job if that is available.
2.       If restart is not available, delete the job, then attempt to upgrade again.

>> For the case of status stuck on “Removing”:
1.       Try to restart the job if that is available.
2.       Else, Remove the job. (continue to step 3)
3.       Then, go back to the Manage Form Templates and try again to Remove the form template.

In simple terms, open the Timer Job Definitions and open the wsp entry you are having the problem with and delete it. Now go back to the ‘Manage Form Templates’ page and delete the problematic form template.

How To: Choose between InfoPath Browser Forms and Custom ASPX Forms

Choosing between InfoPath forms and ASPX pages, depends totally on the nature of the problems we are solving on one side and level of skill set we are investing in solving that problem on the other side. Usually, in most cases, any manager or developer would want to use InfoPath Forms part of Office 2007 because it’s quick and easy. But, as the requirements get more complex and requires more and more customization, one might feel its better to go with ASPX pages and Visual Studio 2005 and SharePoint designer. Technically, InfoPath Forms by itself is incomplete; It needs a container which is again an ASPX web form using the XmlViewer web part. If we go with custom ASPX form, then it has to be designed either using SharePoint designer or Visual Studio leveraging web parts to show the required forms. So for this, developing web parts and its complexity needs to be taken into consideration.

So, to decide on one, we may have to take the decision step by step.

  1. If the requirement is for a single form and showing data from an external data store or from within SharePoint, then going with InfoPath Forms is recommended.
  2. If it’s a single form and needs complex actions, to and fro between the form and the data store, then choosing custom aspx pages is recommended.
  3. If the requirement needs wizard kind of feature i.e. which requires user to go through multiple screens, then custom aspx is the solution.
  4. If the data submitted through the form has to be saved to multiple locations (database, SharePoint, file storage) then InfoPath Forms is a good solution.
  5. If the requirement is for designing numerous forms which are simple enough and well documented, then InfoPath Forms should be considered. InfoPath can help deliver the solution in a short time period.
  6. InfoPath browser based forms has few limitations on the repository of controls one can use. For example: combo box, master/detail view control and many advanced controls are not supported in browser based InfoPath Forms. Depending on these limitations we have to decide on InfoPath or ASPX. ASPX has no such limitations.
  7. InfoPath forms is based on XML. The form is rendered using XSLT stylesheets and the data submitted through the form is available in XML format. The data is well structured to retrieve later on and dump the data/forms in some external system. This in combination with BizTalk server is a perfect architecture for document transition through multiple levels.
  8. InfoPath forms certainly have an edge over ASPX forms as a quick and neat solution. It has some complex out of the box controls, like date picker, file attachment control, repeating sections. InfoPath forms can also have code-behind if needed to manipulate the data on the form or behind the form.
  9. ASPX can have and do everything InfoPath Forms does, with an exception of additional development effort. Apart from it, the deployment process of aspx forms is much better and easier than InfoPath Forms.

Below are some of the excerpts from few blogs I follow which provides some valuable input comparing InfoPath and ASPX forms. Below are the Pros and Cons in using InfoPath Forms:

Pros:

  • Ideal for simple forms
  • Easy to build a form – no coding involved
  • InfoPath form itself is an xml document.
  • Support versioning
  • Works very nicely with SharePoint custom workflows as a workflow association tool.
  • Fully integrated in Microsoft Office 2007 suites like Outlook e-mail messages that can be deployed as Outlook e-mail messages, so colleagues can complete forms without leaving the familiar Outlook environment.
  • Firewall friendly. InfoPath Forms Services make it easy to extend forms solutions beyond firewall because of using many different Web browsers and mobile devices.
  • InfoPath can easily convert Word documents and Excel spreadsheets to forms and build templates to work with.
  • InfoPath provides data integrity and version control for document management purposes, and add structure to information gathering by converting legacy documents to rich InfoPath form templates.
  • Design of a form is much easier in InfoPath forms with a simple drag-and-drop interface and provides support for prebuilt template parts and shared data connections.
  • Creates PDF or XPS and other important document formats and is extensible by addition of a free plug-in to install third party tools and components for document, archival and records management
  • Fully integrated with MOSS 2007 and capable of using integrated workflow management tools in Office 2007
  • Fully Web browsed technology, includes a design checker to help ensure consistency for forms.
  • Support for information rights management to help manage permission control and building a powerful document management team site.
  • Fully centralized for entire organization and enables organizations to centrally

Cons:

  • A web browser-enabled InfoPath form does not support all features of InfoPath client.
  • Inflexible — Difficult or impossible to customize (well, you can argue that you can hack the xsl file of InfoPath)
  • No support for image buttons
  • No support for html
  • No support for tree control
  • Difficult to support Forms Based Authentication
  • By default, InfoPath cannot support SharePoint web services data connections in FBA.
  • Forms Services does not support username() function in FBA. This means that InfoPath form does not recognize the current user.
  • Difficult to perform automated web test against Forms Services.
  • Difficult to support automated deployment. Basically, you have to unzip the xsn file and programmatically modify the manifest.xsf file, and zip back to the xsn file for automated publishing.
  • The way that Forms Services supports deployment of InfoPath forms is quirky – It creates SharePoint solution packages with GUID and creates features with meaningless names on the SharePoint Features folder.

Below are the blog links which talk more about this topic:

http://www.jyhuh.com/blog/archive/2008/03/02/AspNet_vs_InfoPath_Forms_Services.aspx

http://office12.blogspot.com/2007/06/infopath-web-forms-vs-aspx.html

InfoPath Forms – Minimize and Maximize Sections or Collapsible Sections

Recently, I have been working on a project, in which we used InfoPath extensively for designing various forms. Many of the forms has repeated information which we categorized as Header, Footer, Tracking Details etc. InfoPath template parts helped in this aspect.

Having solved that, the form still looks a little bit huge with many fields most of which are pre-populated and the user doesn’t have to worry about them. So, I thought having them collapsed initially by default and provide the user a way to maximize and minimize(collapse) the various sections would solve this issue. Something like below. See the screenshots.

At first thought, we go about searching for those tiny buttons to use for the maximize and minimize, instead there is a tricky way to do this which Microsoft uses in many windows applications. Just drop 2 buttons and put the label as 3 and 6. Now, selecting the buttons, change the font to “Marlett”, boom!, you will see the buttons changed to nice tiny triangular buttons. To make it even better, right click the button, select border/shading and select None for outline. This will merge the buttons with the background. See the below screen shots:

  1. Just put those 2 button in a single row table and place the table above the section, you want to minimize/maximize.
  2. Add a boolean field to the datasource lets say, sectionToggler. Set default to false.
  3. Open the conditional formatting settings for the section: add rules to hide it if sectionToggler = false and show it(not hide) when sectionToggler = true.
  4. Add rules on the buttons: to set the sectionToggler value to true or false depending on the button.
  5. Open up the conditional formatting settings for both the buttons and add rules to hide it based on teh sectionToggler.

More links: