Microsoft InfoPath 2010
The official blog of the Microsoft InfoPath team
• #### XPath Powers: Calculating Totals

InfoPath makes it trivial to track totals for repeating structures, such as customer orders. Just create a repeating table of line items, and sum up the totals for individual line items. However, sometimes, totals for line items may not be available; it is still possible to perform dynamic calculations across the repeating structure, even when interim results (line item totals) are not stored in the data source. This article will explain a way to make this work without code.

Let's explore the simple case first.

 Form at Runtime Data Source

Line item total is set by using a default value (price * quantity) on the lineItemTotal node. Creating an order total is just a matter of adding an expression box that uses the built-in SUM function:

sum(my:group1/my:lineItems/my:lineItemTotal)

And voila, we're done, totals will be calculated correctly.

The reason why we are here: the complex case.

What if the interim results (line item totals in our scenario) cannot be persisted in the data source? This situation might arise if you're operating on a fixed schema, or if you're an "XML purist" (I know I am :-)), arguing that there is unnecessary redundancy in your XML if you store calculated values.

The goal is still the same - but the data source is different.

 Form at Runtime Data Source

The line item total would be an expression box instead of the text box; it would be calculated simply as (price * quantity).

But how do we calculate the order total? Your first instinct may suggest to use sum (price * quantity), but you'll soon discover that the SUM XPath function only takes a nodeset...

Let's recall the clever technique of iterating through repeating items by using just XPath: it was described in detail in this article. Let's use the following value for the order total expression box:

sum(xdMath:Eval(my:lineItems, "my:price * my:quantity"))

Why does this work? Let's go inside-out:

1) The eval function evaluates the price * quantity expression in the context of line items, and returns a nodeset with the results.
2) The sum function takes in a nodeset as a parameter, and sums up its contents, giving us the desired total.

I'm attaching a sample form template that has this technique implemented; save the XSN locally before opening it up.

This method works in InfoPath 2003, 2007, and is supported in browser-enabled form templates.

Alex Weinstein
Program Manager

• #### Information Rights Management: Protecting Forms

In a recent post, we discussed ways to protect sensitive data in your InfoPath forms. This article will drill down on one of these mechanisms - Information Rights Management, a.k.a. IRM. InfoPath 2007 features the ability to set permissions on both the form template that you’re designing and the forms that are based on it. You can choose to restrict who can read or write your form/form template, as well as whether read permissions include the ability to copy, print, etc. This feature is available in the both the designer and editor by clicking the Permission button on the Standard toolbar:

Form instance permissions
When filling out a form, users can set permissions for that particular form. Clicking on the Permissions button in the Standard toolbar will pop up the following dialog:

The user that created that instance of the form will have full control permissions and can grant read or write permissions to other users. Users that do not have any permissions to that form will not be able to even open it.

This feature can make InfoPath a great tool for scenarios where some degree of privacy is required, for example, feedback to a manager to peer.

Form template permissions
In addition to setting permissions for each individual form that is filled out, InfoPath also provides Permission functionality for the form template. When designing a form template, clicking on the Permissions button will pop up the Permission dialog:

The ‘Restrict permission to this form template’ checkbox at the top will initially be unchecked – check it to turn on Permissions. You will then be able to select users or groups that will have different levels of permissions for this form template.

Keep in mind that this area only allows you to control access to the form template itself, not to the forms that are based upon it. To restrict permissions to the forms based on this form template, you would check the second checkbox, ‘Restrict permission to forms based on this form template’:

As mentioned for users setting these permissions in the editor, the user that created the instance of the form will always have Full Control permissions for that form instance, but you can get more specific by clicking ‘Change permissions…’. Here you’ll be able to select who will have Read and Change permissions and which additional features will be available to users.

If you are designing a form for your specific team, you can take advantage of this feature to only give Write rights to members of the team. Everyone else can be given Read rights.

When working with InfoPath forms or form templates that have restricted permissions, you can select an account to access the content with. For example, if your personal e-mail address does not have permissions to view an expense reporting form, you can set InfoPath to use your work address instead.

You can access this feature by clicking on Manage Credentials in the File menu:

Thanks all. I hope you find this useful.

One thing to keep in mind is that IRM is not a security feature – there are ways to get around it. It’s there to make it more difficult for users to accidentally or maliciously tamper with sensitive data.

Bojana
Program Manager

• #### Relinking forms and form templates

We often see issues when people move forms and templates from one location to another. In fact, the linked nature of InfoPath forms and templates is probably one of the hardest aspects of InfoPath to understand. While the complexities can sometimes seem burdensome, the truth is that the overall model is actually quite simple. Once understood, all it takes is a few small tricks and you will find that moving forms and templates isn’t really that difficult. Moveover, you will have a much better understanding of how InfoPath works.

The Basics

InfoPath works by associating a form instance with a form template. The way we do this is typically through a URL association. When you design a form template, it stores the entire description of how the form functions. When published, the form template is put in a location we refer to as the publishUrl (though we expose this in the publish wizard as the access path). Regardless of the name, the key point is that the form template resides in a well known location.

Once published, the form template can be used to create new form instances, or just forms. When you create a form against InfoPath, we save the data as straight XML and associate this XML with the form template via a URL. With the URL we know how to associate the form design (layout, business logic, validation, code, etc) with the form.

The Diagnosis

As you would expect, things get wonky when the association fails to resolve correctly. This typically manifests itself in one of two ways:
1) A form won’t seem to update itself when you publish a new version
2) A form just plain won’t open

You can usually tell pretty quickly if this is really the issue by creating a new form from the published form template and comparing the processing instructions (PI’s) between the old forms and the newly created form. What you are looking for is this (I have omitted some content for clarity):

<?mso-infoPathSolution solutionVersion="1.0.0.200" productVersion="12.0.0" PIVersion="1.0.0.0" href="http://server/site/template.xsn"?>

If the two form files don’t have the same href attribute in the PI, then you have yourself a linking issue.

The Remedy

Once diagnosed, the problem is actually quite easy to fix and can be done in one of several ways. Let’s take a look…

Hand Edit: The most obvious solution is to simply change the href attribute in the PI to point to the correct form template. You can do this by opening the XML file in your favorite text editor and just correcting the href attribute to point to the correct location. This works great for one or two files but is tedious and mind numbing if you have more than a handful.

Re-Link: If your form template is in a Windows SharePoint Server form library, then you can use the built in re-link feature to manage the re-linking for you.  Simply move the forms from the old location to the new form library. Once there, you can force a re-link operation. In WSS v2, you can do this by opening the form library, selecting Modify settings and columns, and clicking on the Relink forms to this form library link. In WSS v3, you can access the re-link functionality by selecting the Relink Documents view from the View dropdown. When you perform the re-link, WSS will scan all the XML files for the href in the PI and if it doesn’t match the location for the template associated with the form library, the PI will be updated.

PIFix: Finally, if your forms and your form template are living on a file share somewhere, then you can use the PI Fixup tool (pifix.exe) provided in the InfoPath 2003 SDK. This tool will allow you to process any number of input files and change attributes in the form to match your target form template.  Follow the instructions in the SDK or the tool to re-link your form files.

Caveats

As with any “under the hood” job, there are caveats.  You will want to make sure you understand what you are doing so you don’t wind up with “extra parts,” as it were.  When changing forms to work against different templates, there are two major things you want to think about before you re-link:
1) Schema changes
2) Versioning

Schema changes are perhaps the most serious issue because they can create data loss if you aren’t careful. By default, InfoPath enforces schema when opening forms against templates.  If the forms XML doesn’t match the schema, we don’t load it. By default, InfoPath works to address this by performing version upgrades on the XML when it doesn’t match the schema. This is great because you don’t need to worry that existing forms will break when you make changes to the form template. However, keep in mind that when elements and attributes don’t match the form template schema, existing data may be deleted to make the form schema compatible. Here is what happens:
- Add elements/attributes: No worries. If you add elements or attributes to the form template, InfoPath silently adds the element or attribute to the form XML.
- Delete elements/attributes: Think about it... You deleted the elements and attributes from the form template, so we will remove them from the XML file too. Chances are you didn’t need it anyway (why delete it otherwise?), but you want to pay attention here.
- Move elements/attributes: Really think about it... When you move an item in the form template’s data source, we treat that as a delete and then an add.  So be aware that data might disappear!
The bottom line, make sure you understand the schema implications of linking your form to a potentially different form template.

Versioning issues can cause minor headaches but don’t impact the ability of the form to open nor contribute to possible data loss. The key here is to make sure the solution version attribute in the form’s PI is less than that of the published template. You can find the version number of your form template in the form options dialog as seen below:

If the form’s version is higher than that of the form template, the you will simply receive a warning message when opening the form telling you that you are opening it against an older template.

Nathaniel Stott
Program Manager

• #### Extended data validation for the Multiple-Selection List Box in InfoPath 2010

Hi, Frank Mueller from the InfoPath development team here. The Multiple-Selection List Box (MSLB) control was introduced in InfoPath 2007 to enable users to select multiple items from a list when filling out forms. In this post, I will explain the different ways you can restrict and validate the data entered using this control in InfoPath 2010. I will also cover some advanced tips and tricks.

### In this post:

Data Validation

### Example Usage:

First let’s look at a scenario where you may want to use the MSLB control. Say, for example, you are building a form for customers to order your company’s products. To be able to more effectively spend the company’s marketing budget in the future, the marketing department would like to know how your customers found the company’s web site. So you’ve added a Multiple-Selection List Box to gather responses to that question.

Your customers can now select one or more options. If a customer heard about the web site through a channel that is not specified in the Multiple-Selection List Box control, he/she can select the last checkbox and just type in a custom response.

## Data validation

The marketing department is pleased with the new order form, but many customers do not bother responding to the “How did you hear about us?” question. With InfoPath 2010, solving this problem is very easy.

In InfoPath 2010, there are two main ways that form designers can restrict and validate the data entered using the MSLB control.

1. Require that at least one item be selected (At least one selection required) (NEW in InfoPath 2010)
2. Require that every selected item have a value (Cannot be blank)

### Require that at least one item be selected (At least one selection required) (NEW in InfoPath 2010)

New in InfoPath 2010, we can now enforce that users select at least one non-blank item by setting the “At least one selection required” property. In most cases, this is the setting that you will want to use.

When you preview the form, you will notice a red asterisk in the upper right corner of the control, indicating that a selection is required.

If you select a blank custom value, an asterisk will appear in the top right hand corner of the custom value text box.

All asterisks will disappear as soon as you select an option that is not blank, or you select the custom value text box and type in a value.

### Technical Details

The new type of data validation is only applicable to repeating fields that are bound to Multiple-Selection List Box controls.

When setting the property at the field-level (instead of on the control), you will notice that it’s called “Non-empty occurrence required”. This is because the field can be bound to a control other than the MSLB, in which case users do not make selections when using the control.

You may set any repeating field to “Non-empty occurrence required”, but you will only see an effect when the field is bound to a Multiple-Selection List Box control. “Non-empty occurrence required” is not implemented as an XSD constraining facet, but rather as a special Validation Rule that is stored in the manifest.xsf of your form template. This has the benefit that you can set the data validation even if you are designing a form template based on a locked schema.

### Require that every selected item have a value (Cannot be blank)

In most cases, the “At least one selection required” property will do you what you need to ensure that users enter the required data.
In InfoPath 2010, we still support the legacy “Cannot be blank” property. When this property is set, it requires that every item that a user selects from the list has a value. It does not however require that users select an item in the first place.
When you preview the form, you will notice a red asterisk, whenever you select the checkbox of the custom value text box. This indicates that if the user wants to select this option, a value has to be typed in the text box before the form can be submitted. Once you type some text in the custom value text box, the asterisk will disappear.

### Technical Details

When a field in an InfoPath form is set to “Cannot be blank”, a minLength constraining facet is applied to the XSD element, which requires that corresponding XML nodes contain at least one character.

<xsd:element name="field1" type="my:requiredString"/>
<xsd:simpleType name="requiredString">
<xsd:restriction base="xsd:string">
<xsd:minLength value="1"/>
</xsd:restriction>
</xsd:simpleType>

This makes sense for text fields, when the form designer wants to ensure that the person filling out the form has to enter data into the field before it can be submitted for further processing.

The Multiple-Selection List Box control is bound to a repeating field in the form’s data source. When the user fills out the form and makes selections in the control, a new XML node is created for each selection made. If you mark the repeating field that the control is bound to as “Cannot be blank”, InfoPath will ensure that all options selected or entered through the custom value textbox are not blank. However, if no selections are made in the control, no XML nodes are created, and hence the constraining facet of the field is not violated, and the user is not forced to make a selection.

When would I want to use “Cannot be blank” instead of “At least one selection required”?

If you want to ensure that users do not select any item that does not have a value then the “Cannot be blank” property can be used.

In the example below, both “At least one selection required” and “Cannot be blank” are set. The data is not valid because the custom selection is blank.

In the example below, only the “At least one selection required” is set. The data is valid because at least one non-blank item is selected.

### Special behavior in customized SharePoint list forms

In a SharePoint list, when you mark a Choice column as required, it requires users to select at least 1 item and for all selected items to have values.

Marking the field as required in SharePoint, has the same effect as setting both the “Cannot be blank” and “At least one selection required” properties in InfoPath.  For consistency with SharePoint, when customizing a SharePoint list form in InfoPath 2010, only one data validation option, “Cannot be blank” is available.

### Removing Blank Default values

When designing the order form described above, InfoPath will by default insert a blank default value node for each repeating field. As you preview the form you will notice that the custom value text box at the bottom of the Multiple-Selection List Box control will be checked by default.

If you wish there to be no default selection at all in the control, you need to remove the default value node.

1. Click on the File button
2. Select Form Options under the Form Information tab
3. Select the Advanced category in the Form Options dialog
4. Click on the Edit Default Values … button
5. Click on the pluses in front of the fields to expand the data source until you can see the repeating field that is bound to the Multiple-Selection List Box control
6. Uncheck the checkbox in front of the repeating field

7. Click OK to close both opened dialogs
When you preview your form now, you will notice that the custom value checkbox is not selected by default.

Frank Mueller
InfoPath Developer

• #### Take a list offline using SharePoint Workspace 2010

In this short video demo, Shirish Pulikkal from the InfoPath test team shows how you can customize a SharePoint list in InfoPath designer and work with the list offline in SharePoint Workspace.

The Scenario: A fictitious company Fabrikam wants to track assets in their lab using SharePoint list. They want to be able to track assets both in the online and offline case. Fabrikam has decided to use InfoPath to customize the list and SharePoint workspace to enable working offline with the list.

The Process: We start by customizing the form for the SharePoint list in InfoPath designer and add a secondary data connection to pull data from another SharePoint list. Then we publish the form back to the SharePoint list and sync it in SharePoint Workspace. Now we can create list items while working offline in SharePoint Workspace and items can be synced to SharePoint server when we get back online.

• #### Upgrading InfoPath 2007 forms with Person/Group Pickers to InfoPath 2010

Hi, this is Frank Mueller again and this is the second of two posts that I’ve written about the InfoPath 2010 Person / Group picker control. InfoPath 2007 form templates containing the Person/Group Picker control (formerly named Contact Selector) will continue to work in InfoPath 2010 the same way they used to as long as the form template remains in the InfoPath 2007 Form Template format. However, if you wish to upgrade your form template to InfoPath 2010 to take advantage of newly added functionality for the control (see this blog post for more details) or other exciting new features, you will have to perform the steps outlined in this post in order to use the Person/Group Picker.

 Attention: If you follow the steps outlined in this blog post to change your form template, you are changing the data schema of the form template. This means you will not be able to view any previously filled out forms with the new form template. In order to avoid data loss, you should create a new InfoPath 2010 version of your form template and publish it to a different location. This way you can continue to view previously filled out forms with the InfoPath 2007 version of your form template.

### Saving the form template in InfoPath 2010 form template format

1. Click the File button and select Save As
2. In the Save As dialog select the corresponding InfoPath 2010 Web Browser or Filler Form Template in the Save as type dropdown.
3. Change the file name to be something different so that you don’t overwrite your existing form template
4. Click Save

### Removing existing versions of the control from the form

After the form template is saved in the new format, you will notice that each Person/Group Picker in your view will show the following error message when you hover your mouse cursor over it.

Also the Design Checker task pane appears, indicating that the version of the Person/Group Pickers in the view is not compatible with InfoPath 2010. For each Person/Group Picker in all views, do the following:

1. Select the Person/Group Picker control in the view
2. Notice that the XML node tree that the control is bound to will be highlighted in the Fields task pane (if the Fields task pane is not visible, click Show Fields on the Data tab in the Ribbon).
3. Delete the highlighted XML node tree by deleting the root node in the Fields task pane (Right-click the node, and select Delete from the context menu)
4. Select the Person/Group Picker control in the view and delete it
5. Use the Controls Gallery on the Home tab to insert a new Person/Group Picker at the position in the view where you just deleted the control
6. Right-click the newly inserted control in the view and select Person/Group Picker Properties from the context menu
7. In the Person/Group Picker Properties dialog select the SharePoint Server tab
8. Type in the URL of the SharePoint site (If you don’t know the SharePoint site that the control used to connect to, please follow the optional steps at the end of this blog post.)
9. Click OK to close the dialog

### Testing the Person / Group Picker

Preview the form in InfoPath Designer or publish the form to a SharePoint site (be sure to publish to a different location in order to be able to view previously filled out forms) and view the form, enter a name or logon alias, click the “Check Names” button and resolve the name! Alternatively you can click the “Address book” button to perform a search if you do not know the complete name of the user.

### Configuring advanced SharePoint list control properties (optional)

To configure advanced control properties  that are new in InfoPath 2010, such as limiting the entities the control can pick, as well as requiring the control to contain data before the form can be submitted, follow the steps in this blog post.

### Determining the SharePoint site URL (optional)

If you added the control to your InfoPath 2007 form template following the steps outlined in this blog post, you will have created a data connection called Context, which specifies the SharePoint site the Person/Group Picker should connect to. Follow these steps to recover the data connection XML file and obtain the URL of SharePoint site:

1. Start InfoPath Designer 2010 and open your InfoPath 2007 form template
2. Click the Data tab and select Resource Files
3. In the Resource Files dialog select Context and click on the Export button to save the data connection XML to a location on your hard drive.
4. Open the XML file in a text editor (e.g., notepad)
5. Write down the siteUrl to configure the Person/Group Pickers

# InfoPath Developer

• #### Cool Forms! NCAA March Madness Bracket

This week’s cool InfoPath form is a browser form used to run a bracket tournament at Microsoft. The form uses filtered dropdowns to let users make their picks for NCAA March Madness 2010, and uses conditional formatting to show correct and incorrect picks as the tournament progresses. There’s also a printable view that shows the full bracket on one page, making it easy to print your bracket and show it off to your co-workers.

The form contains several data connections to SharePoint lists containing participants and results, which means that updating the results is as simple as editing a SharePoint list item, and doesn’t involve changing the form at all.

Edit View (click to see larger image):

Display View (click to see larger image):

Print View (click to see larger image):

For details on how we created the filtered dropdowns in this form, see Use Rules and Filters to Create Cascading Dropdowns.

If you have a “cool” form that you would like to share with us, please send an e-mail with the following details to coolform@microsoft.com -

• Attach 1 or 2 screenshots of your form
• Provide a brief description of the form
• You may also attach the XSN file (optional)

The most popular submissions will be featured on our blog in future posts.

Check out other Cool Forms! here.

• #### Using Relative URLs with the ServerInfo Class in InfoPath 2010

Hi, my name is Jill Anderson and I am a tester on the InfoPath team. In this post, I would like to introduce you to the one of the newest members of the InfoPath Object Model, the "ServerInfo" class.  For InfoPath forms published to a SharePoint server, the members of this class give you context about that particular site. Documentation about this new class can be found at: http://msdn.microsoft.com/en-us/library/microsoft.office.infopath.serverinfo.aspx.

In this short video demo, I show you how you can use the members of this class to enable your form to submit data using a relative URL.  This enables you to package a Site Collection as a WSP and move it to a new server.  With these changes, the submit data connection moves to the new server as well.

# Initial Setup:

To make sure that my form template was correctly associated with my SharePoint Form Library both before and after the Site Collection Migration, I published it as a Content Type (http://office.microsoft.com/en-us/infopath-help/create-a-sharepoint-library-or-site-content-type-for-your-form-template-HA010103005.aspx ). The ability to publish a Sandboxed Solution as a Content Type is a new feature for Office 2010.

Afterwards, I associated this content type with the correct SharePoint Form Library on the SharePoint Server. The steps to do this are as follows:

1. Create a new "Form Library"
2. Open the newly created "Form Library"
3. Open the "Library Settings" located under the "Library" Tab on the Ribbon
4. Open "Advanced Settings" and set "Allow management of content types?" to "yes".
5. Under "Content Types" select "Add from existing content types"
6. Add the content type you published to the SharePoint server.

# Sample Code:

This is the code I used to relativize the submit to the SharePoint site.

```/// <summary>

/// Submits the form to the SubmittedTimeCards form library on SharePoint and calls a function to update the Vacation

/// and Sick Balance for the employee.

/// </summary>

/// <param name="sender">The source of the event.</param>

public void FormEvents_Submit(object sender, SubmitEventArgs e)

{

FileSubmitConnection fileSubmit = (FileSubmitConnection)this.DataConnections["SharePoint Library Submit"];

// Refreshing the Total number of hours and total pay for this given form.

this.CalculateWorkWeekHours();

this.CalculateTotalTypeHours();

this.CalculateTotalPay();

// Update the new Sick leave and Vacation Balance.

this.DeductVacationAndSickPay();

// Relative the SharePoint Submit location to current SharePoint site.

fileSubmit.FolderUrl = this.ServerInfo.SharePointSiteUrl.ToString() + "SubmittedTimeCards/";

fileSubmit.Execute();

// If the submit operation is successful, set

e.CancelableArgs.Cancel = false;

}

```

Introduction to Sandboxed Solutions - Sort data in repeating tables using managed code
Jill

• #### Peer to Peer Solutions using SharePoint Workspace 2010

In the 2nd of 2 videos about InfoPath 2010 and SharePoint Workspace integration, Shirish Pulikkal from the InfoPath test team shows how to create and maintain an Asset Tracking list for both online and offline use, using InfoPath designer and SharePoint Workspace.

The Scenario: In the 1st video, Taking a list offline using SharePoint Workspace 2010, Shirish showed how to take a SharePoint Asset Tracking list offline in SharePoint Workspace. Smaller organizations with budget constraints may not have access to a SharePoint Server. In this video we show you how to create and maintain an Asset Tracking list for both online and offline use, using just InfoPath and SharePoint Workspace.

The Process: We use an Asset Tracking form and Categories form for the demo. Initially the Categories form is imported into SharePoint Workspace and we enable lookup to the list tool containing the Categories form. Next we design a new form for Asset Tracking from within SharePoint Workspace and add a SharePoint Workspace data connection to the Categories form. Then we import the Asset Tracking form in list tool in SharePoint Workspace, publish the tool and make the form available to other users subscribed to the workspace to create new list items. This is an example of a peer to peer scenario. The changes you make in your workspace will be immediately visible to other users subscribed to your workspace.

• #### InfoPath 2010 Public Beta is Here!

The InfoPath team is excited to announce the release of the Office 2010 and SharePoint Server 2010 public betas! For the 1st time members of the public can download InfoPath 2010. Download it now from www.microsoft.com/2010!

Here are just some of the highlights in this new release. (For more details, see our earlier What's New in InfoPath 2010 post).

Quick and Easy Form Design

• Designing good looking forms has been made easier with our new page layout templates, layout tables, and themes.
• With our new out-of-the-box rules and improved rules management UI, you can easily add rules to validate data, format your form, or perform other actions with just a couple of clicks, and without any code.
• Our new “quick” publish functionality allows you to publish forms in a single click (no more clicking through the Publishing Wizard every time you want to make an update to your forms!)
• New Controls include the picture button, signature line control and person/group picker which is now available out-of-the-box in the controls gallery.

SharePoint Integration
Over the past 3 years of product development, we’ve made huge investments in integration with the SharePoint platform to make it much easier to build rich forms-based applications on top of SharePoint Server 2010.

• Using InfoPath, you can now extend and enhance the forms used for creating, editing and viewing items in a SharePoint list.
• With the new InfoPath Form Web Part, you can host your forms on portal pages without writing a single line of code.
• With SharePoint sandboxed solutions, forms with code can be published directly to SharePoint libraries without requiring administratror approval.
• Richer browser forms:Bulleted, numbered, and plain lists, multiple selection list boxes, Combo boxes, Choice group and sections, and Filtering functionality are now supported in browser forms.
• InfoPath Forms Services Administration and Management: We have invested in many improvements to make it easier to manage InfoPath Forms Services as a component of Microsoft SharePoint Server 2010. These include Powershell commandlets to automate tasks and SharePoint Maintenance Manager Rules to monitor the health of your server.

Introduced since the technical preview, InfoPath now supports connecting to REST Web Services.

Enjoy!

The InfoPath Team

• #### InfoPath 2010 is unveiled at the SharePoint Conference

As many of you may know, the SharePoint Conference 2009 is taking place this week in Las Vegas, Nevada and it's been a particularly exciting week for the InfoPath product team. Over the past 3 years of product development, we have made huge investments in integrating with the SharePoint platform. Finally, this week, we got the opportunity to unveil the fruits of these investments to the world, and so far, the reception has been tremendously positive! (Check out what people are saying about InfoPath 2010 on Twitter.)

SPC is taking place at the Mandalay Bay Hotel:

InfoPath Booth:

(from left: Umut Alev - development lead, Peter Allenspach - group program manager, Rick Severson - test lead):

InfoPath 2010 is well represented at this year's conference with a total of 5 sessions. The 1st session took place on Monday and was presented by Peter Allenspach and Bojana Duke from the InfoPath program management team.

The InfoPath session drew big crowds:

The session opened with an introduction to InfoPath 2010, followed by 3 feature demos which illustrated just how easy InfoPath 2010 makes it for Information Workers to create their own solutions without reliance on IT departments. Some highlights below -

InfoPath 2010 Overview:

Demo 1: Customizing a SharePoint list form

In this demo, Peter and Bojana walked through a real Microsoft internal College Recruiting scenario. Employees use SharePoint lists to sign up for recruiting trips. Bojana wowed the audience by taking the Recruitment Trip list form and customizing it in InfoPath in under a minute!

Peter and Bojana then went on to show how this form could be further enhanced and customized. Our new out of the box rules were used to add data validation and to conditionally show or hide sections in the form. A data connection to the Colleges list was added to pull details about the colleges into the recruiting trip sign-up form. The form layout was customized using our new pre-built layout tables and themes. They then showed how in a single click, the form could be published to SharePoint. Not only that, but they then showed how the list, including the customized form could be taken offline in SharePoint Workspace.

Last but not least, they opened the form in Firefox showing that you can use your browser of choice to fill out your forms.

Before Form:

After Form:

Offline Form in SharePoint Workspace:

Demo 2: Creating Mashups using the InfoPath Form Web Part
The 2nd demo took the Recruiting scenario to the next level. In this demo, Bojana created a simple portal page with 2 Web Parts, the Recruiting trip list and the new InfoPath Form Web Part. In only a few clicks, she connected the 2 Web Parts. Now when she selected an item in the recruitment list, the details for that trip were displayed in an InfoPath form.

Portal Page:

They concluded the 2nd demo by showing that both SharePoint solutions and InfoPath forms are truly portable and reusable. The site was saved as a template (WSP) and a new site was created from this template. The SharePoint list, portal page and InfoPath form were fully functional on this new site.

Demo 3: Office Business Applications: Procurement scenario
In this final demo,  Peter and Bojana showed the audience how InfoPath helps IT departments develop full Office Business Applications on the SharePoint platform. They used a procurement scenario to demo these capabilities. In this scenario, an employee submits a request to purchase a new laptop computer. The solution used an InfoPath form that connects to a vendor database, that brings in details about the goods you can purchase.

Procurement Form:

This type of application can be built in SharePoint Designer, using web part pages to create the user experience. The data can be stored in form libraries, SharePoint lists, and external systems using Business Connectivity Services. If InfoPath rules don’t do the job of defining the desired form behavior sandboxed or full trust code can be added to the forms. SharePoint workflows can be used to send e-mail notifications and track status. And once you’re all done, you can package your application so it can be tested and eventually deployed to the production servers.

Procurement Portal Page:

This first session set the stage for the remaining InfoPath sessions of the week:

• Building Applications with InfoPath and SharePoint Designer (this session took place on Tuesday - more details to follow)
• Performance Best Practices for Forms Applications
• InfoPath 2010: Form Design Best Practices
• Form-Driven Mashups using InfoPath and Forms Services 2010

Stay tuned for more updates from Las Vegas!

• #### Complex Data Validation

How do you test more than 5 parameters? How do you group parameters? One answer to both questions, is to have multiple validations in one statement. We'll look into these problems in detail in the case studies below.

Case Study #1

Problem: a form designer wants to use this logic:

IF (State="Ohio" or State="Alabama" or State="Arizona" or State="Georgia" or State="Utah" or State="Idaho" or State="Iowa") THEN (fail...)

Since the Validation UI only supports 5 statements, you run out of room before entering all of the tests.

Solution: Put more than one test in a statement. If you aren't sure of the syntax, follow along.

Enter the first three tests.

Click [OK] to close the dialog. Notice that the syntax is displayed in this dialog:

Click [Modify] and use this syntax.

When you change the first column to "The expression", you will see how to refer to the field you are checking. This differs depending on if you are checking the current field or a different field. In this case, State is the selected field, so we can enter the validation like this:

If you OK this and then come back to it, InfoPath will automatically break out the last 4 tests into separate statements. This makes it easier to see more of the conditions that are being evaluated.

Case Study #2

Problem: a form designer wants to use this logic:

IF (State="Ohio" or State="Alabama") and TaxRate is blank THEN (fail...)

Using just the default Validation UI, you can't group tests like this.

Solution:  Put more than one test in a statement. Again, if you aren't certain of the syntax, enter the tests in the Validation dialog:

Click [OK] to close. Note the syntax in this dialog:

Click [Modify], and use the syntax shown in the Validation statements.

Alternative Approach

Another way to handle both of these scenarios is to use multiple validations:

This will work and in some cases would be easier to follow (the 50 states could be listed and you could scroll the Validations).

Performance may be better in one or the other, but that would depend on the logic you are validating.

All of these statements are evaluated. There is not an implied "and" or "or" combining them. In this last example, if you were checking the "State = ...  OR TaxRate is blank", both would fail. You could check the number of errors and would get 2, even though only 1 error message would be shown (the first one).

Jerry Thomas
Software Design Engineer in Test

• #### IE7 is here

Our friends from the Internet Explorer team are celebrating a major milestone - the release of Internet Explorer 7. You all know about the great features it brings to browser users (security, performance, ease of use); you may have seen them first-hand by trying out their Release Candidates.

You may be wondering - how does this affect InfoPath? From the first look, there shouldn't be much connection, but there is.

InfoPath ‘s editing surface is built on top of Internet Explorer. This means that most things that you see when you fill out an InfoPath form are, really, just clever HTML elements. Internet Explorer 7 brings improved implementations - thus, InfoPath users will benefit from the IE7 install, too.

Some specifics:

• IE7 provides a windowless SELECT control, which brings better performance for InfoPath forms that use the Drop Down List Box, List Box, or Combo Box controls .
• IE7 offers full type-ahead support for dropdowns: for example, if a dropdown contains {"apple", "banana", "orange"}, then typing "ba" with the focus on the control will take you to "banana". InfoPath inherits this perk.
• Overall rendering performance is improved
• Many InfoPath crashes are fixed

This list is relevant for InfoPath 2007. InfoPath Forms Services will benefit just like any other web app.

Bottom line: if your organization uses InfoPath, the returns on deployment of Internet Explorer 7 will be even greater! IE7 will be distributed as a public update; if you can't wait (and I personally couldn't - I downloaded the final release of IE7 the minute I found out it was available), get it here.

Alex Weinstein
Program Manager

• #### Sorting Repeating and Tabular Data

InfoPath is a great way to easily gather and present XML data to the masses. But what about efficiently presenting a massive amount data? Tons of data (e.g., a list of hundreds product names) usually find their ways into lists that we’ll find on SharePoint, in a database, or just sitting in an XML file. Controls like Repeating Sections and Tables are useful mechanisms for displaying lists of data. But their usefulness is limited to how efficiently the user of your form can find and work with such large lists of data. An easy solution to effectively present large lists of data to your users is through sorting that data.

No Sorting Options in InfoPath
Try scouring the Repeating Table or Repeating Section controls’ properties dialogs for anything related to “sort”. Sorry to say, you’ll come up empty handed. That’s why we thought you’d find this blog entry handy. Our goal is to show you how to sort any repeating data and to do so in many different ways: sort by string, sort by number, sort ascending or descending, and even sort by different fields (or columns) in the repeating data. What we’ll show you, in both the code and the design of the view, is designed to be browser-compatible. This means you can publish this form template to a SharePoint server running Forms Services 2007 and fill out the form in a Web browser. Let’s get started.

Figure 1: Filling out the SortingPeople sample form template

The sample form template is attached; download the ZIP to your desktop, expand it, then right-click the XSN and select "Open in Design Mode". This sample requires InfoPath 2007, and will work in the browser when published to InfoPath Forms Services.

The View for the SortingPeople Form Template
To show you how to sort data in your form, we’ll use a concocted example to sort a list of people. As you can see in Figure 1, there are various options to sort the data. Clicking the “Sort” Button triggers the sort otherwise the data is not sorted automatically (more on this later). You can also sort by clicking any of the “Sort by this column” Buttons in the header and footer of any column. There are three columns in the Repeating Table representing our repeating data: Last Name, First Name, and Age. (The string data type is used for the first two columns and an integer data type for the last column.) In Figure 1, we’ve filled out the form with names of famous architects. (Their ages are fictitious.) While we’re not working with enough data to really justify a sort, this example is simply for demonstrative purposes. As you might expect, we can sort the Repeating Table data by any column and by any direction (ascending or descending). At any time we can change the existing data or even add or remove rows. But we would need to invoke the sorting functionality to put things into place again.

The Data Source for the SortingPeople Form Template
To begin designing this form template we started with controls and the data source. We inserted a Repeating Table control and renamed its data source groups and fields to map with our people example. The main data source is shown in Figure 2. To accommodate the various sorting options that we expose via controls at the top of the view (e.g., the Sort By Drop-Down List Box), we’ve added attribute fields under the SortingPeople document element. These attribute fields remember, for example, whether we’re sorting by the Last Name or the Age column.

Figure 2: Data source for the SortingPeople sample form template

Considerations When Sorting Data
Now we’ll look at how we implemented sorting functionality behind this form template. This is accomplished through C# code behind the form. While we could have opted for an easier XSL-based implementation to sorting data, it would not have been compatible with Forms Services. So we’re left to actually sorting the data. There are advantages as well as disadvantages to our approach. Sorting the data is preferred when you want to persist the sorting in the saved or submitted form. While the initial cost is much higher to sort the data in the data source instead of the view, there is much less processing that occurs on subsequent visits to that data because it will already be sorted. If your form template has multiple views, switching to and from a view that performs an XSL sort is very expensive. On the contrary, a sorted data source adds no additional processing requirements on view switches. A final reason why you may want to sort the data in the data source instead of the view: submitting sorted data to a database or Web service may be optimal (or even a requirement) for that backend system.

Sorting Data with C# Form Code
To best understand how we designed the code behind form template to support sorting, we’ll be talking about its C# form code and how it interacts with the main data source. Let’s start by looking at some of the supporting form code that will make it easier for us to implement the sort feature. The properties are used within the sort itself to read the options at the top of the view about how to sort the data. The methods are very useful helpers that we use throughout our sample code.

/// <summary>

/// Returns the "Sort By" Drop-Down value.

/// The value returned by this property MUST match with an item within the Repeating Table.

/// </summary>

private string SortBySelection

{

get { return GetValue("@my:SortBy").Replace(" ", string.Empty); }

}

/// <summary>

/// Does the user want the SortBy by number (true) or string (false)?

/// </summary>

private bool SortAsNumber

{

get

{

return 0 == GetValue("@my:SortAs").CompareTo("number");

}

}

/// <summary>

/// Does the user want an ascending (asc) or descending (des) sort?

/// </summary>

private bool SortAscending

{

get

{

return 0 == GetValue("@my:Order").CompareTo("asc");

}

}

/// <summary>

/// Helper to wrap an int within brackets.

/// </summary>

/// <param name="intToWrap"></param>

/// <returns></returns>

private string WrapAsIndexer(int intToWrap)

{ return WrapAsIndexer(intToWrap.ToString()); }

/// <summary>

/// Helper to wrap a string within brackets.

/// </summary>

/// <param name="strToWrap"></param>

/// <returns></returns>

private string WrapAsIndexer(string strToWrap)

{ return "[" + strToWrap + "]"; }

/// <summary>

/// Helper to get an XPathNavigator's value.

/// </summary>

/// <param name="xpath"></param>

/// <returns></returns>

private string GetValue(string xpath)

{

return Root.SelectSingleNode(xpath, NamespaceManager).Value;

}

/// <summary>

/// Helper to set an XPathNavigator's value.

/// </summary>

/// <param name="xpath"></param>

/// <param name="value"></param>

private void SetValue(string xpath, string value)

{

Root.SelectSingleNode(xpath, NamespaceManager).SetValue(value);

}

/// <summary>

/// Helper to get the document element of the main data source.

/// </summary>

private XPathNavigator Root

{

get { return CreateNavigator().SelectSingleNode("/my:SortingPeople", NamespaceManager); }

}

Next, let’s take a look at the code behind all of the Buttons in our form template. We created these event handlers through each Button’s properties dialog. Their implementations are quite trivial. You can see that adding additional sorting columns to the Repeating Table is a simple task. If you wanted to add a column that doesn’t need to be sorted, there’s nothing to do beyond adding the column in the Table!

public void SortButton_Clicked(object sender, ClickedEventArgs e)

{

SortList();

}

public void LastNameSort_Clicked(object sender, ClickedEventArgs e)

{

SetValue("@my:SortBy", "Last Name");

SortList();

}

public void FirstNameSort_Clicked(object sender, ClickedEventArgs e)

{

SetValue("@my:SortBy", "First Name");

SortList();

}

public void AgeSort_Clicked(object sender, ClickedEventArgs e)

{

SetValue("@my:SortBy", "Age");

SortList();

}

Now the million dollar question: what’s behind the SortList method? Let’s look and then we’ll explain how it works.

/// <summary>

/// Bubble sorts the list of people.

/// </summary>

private void SortList()

{

string sortBy = SortBySelection;

string itemsToSort = "my:People/my:Person";

int numPeople = Root.Select(itemsToSort, NamespaceManager).Count;

// basic bubble sort implementation

for (int i = 1; i < numPeople; i++) // xpath is 1-based

{

for (int j = i + 1; j <= numPeople; j++) // keep j ahead of i; we can index [numPeople]

{

// swap (i,j) if necessary

string iValue = GetValue(itemsToSort + WrapAsIndexer(i) + "/my:" + sortBy);

string jValue = GetValue(itemsToSort + WrapAsIndexer(j) + "/my:" + sortBy);

// Do we sort by number or string?

if (SortAsNumber)

{

int iNum, jNum;

if (!Int32.TryParse(iValue, out iNum) || !Int32.TryParse(jValue, out jNum))

{

// Let InfoPath take care of the invalid datatype with its own validation, we'll keep sorting the rest

continue;

}

if ((SortAscending && iNum > jNum) || (!SortAscending && iNum < jNum))

{

Swap(itemsToSort + WrapAsIndexer(i), itemsToSort + WrapAsIndexer(j));

}

}

else // SortAsString

{

if ((SortAscending && String.Compare(

iValue, jValue, true /*ignoreCase*/, currentThreadCulture) > 0)

|| (!SortAscending && String.Compare(

iValue, jValue, true /*ignoreCase*/, currentThreadCulture) < 0))

{

Swap(itemsToSort + WrapAsIndexer(i), itemsToSort + WrapAsIndexer(j));

}

}

} // end inner-for

} // end outer-for

}

Analyzing the C# Form Code
Let’s break down what we’re doing in this SortList method. First we get the column to use for sorting, the XPath to the repeating group that we want to sort, and the culture of the thread so we respect the current locale when sorting. Next we get the number of people that we’ll be sorting. We need this number because we’ll use it for our bubble sort implementation.

The two nested for-loops implement the bubble sort algorithm. We chose bubble sort because of its simplicity and for demonstrative purposes. (We’d recommend you use the most efficient sorting algorithm based on your requirements.) The variables i and j iterate through the people. We use the iValue and jValue variables to select the data pointed at by i and j to determine if a swap is necessary as part of the sort loop.

Next, we have an if-else statement that checks if the sort is by string or by number. A sort by number will attempt to parse out 32-bit integer values from the iValue and jValue fields. If the parse fails for any reason, we skip this specific comparison and continue trying to sort the rest of the data. Once we have integers, we do a simple comparison and swap if needed. If we’re sorting by string instead of numerical value, we use the static .NET library String.Compare method to make a culture sensitive comparison. A swap is performed if it’s necessary. (Note that we could have combined some code in the SortList method to make it more compact. We left the structure of the code unoptimized for maximum readability.)

The last bit of code we have not yet revealed is the Swap method. This method, as its name suggests, simply swaps the positions of two XPathNavigator objects as identified by their XPaths. (An XPathNavigator is a pointer into an XML tree of data. You can read more about the XPathNavigtor class on MSDN.)

/// <summary>

/// Swaps two XPathNavigators at xpath1 and xpath2.

/// </summary>

/// <param name="xpath1">First XPath.</param>

/// <param name="xpath2">Second XPath.</param>

private void Swap(string xpath1, string xpath2)

{

XPathNavigator item1 = Root.SelectSingleNode(xpath1, NamespaceManager);

XPathNavigator item2 = Root.SelectSingleNode(xpath2, NamespaceManager);

// Make a copy of item1

XPathNavigator item1Clone = item1.Clone();

// Move item2 to item1

item1.ReplaceSelf(item2);

// Make the original item2 be item1 that we cloned earlier

item2.ReplaceSelf(item1Clone);

}

Sorting Automatically
One of the things you might ask is why we decided against sorting the data automatically. The most important reason is user experience and then followed by form responsiveness. Think about what would happen if the Repeating Table rows sorted themselves whenever data changed that required a sort. Say you were entering data into a new row. You start by typing a person’s last name and then either hit tab or click into the First Name field. If the form is sorting by the Last Name field, the row may have jumped to another location relative to the other rows in the Repeating Table! You would expect that you could fill in all of the data for a new row before it sorts itself. There are also other weird cases that automatic sorting would spoil. For example, you would not see a new row added within the middle of the Repeating Table. Why? As soon as you added it, it immediately jumped to the top (or bottom) of the Repeating Table as sorted data. Let’s consider for a moment why we didn’t automatically sort because of form responsiveness; for now let’s assume that we somehow worked out all of the kinks with the user model. Obviously the form will be less responsive in InfoPath, especially on a slow computer, with so much sorting. But the real problem is realized when filling out such an intense form template in a Web browser. Every time code runs while a form is filled out in a browser, the form data is posted back to the server for processing. Postbacks themselves can take several seconds or even minutes depending on many variables including the network connection speed as well as the client and server machines’ performance capabilities. As you can see, an automatically sorting form isn’t necessarily a better form.

Hagen Green
Software Design Engineer in Test

• #### InfoPath-Related Blogs: OPML Compilation

We promised, and here it is: the OPML compilation of RSS feeds of bloggers that write about InfoPath. Just download the file and import it into your favorite news aggregator.

Sneak peek:

Cheers!
Alex

• #### Move Up/Move Down

One stumbling block for developers coming up to speed on InfoPath is that the SDK documentation leads you to the edge of the XML cliff and then goes mysteriously quiet. For web developers who have programmed applications with the MSXML SDK for manipulating XML this isn’t a problem – they brought their parachute with them and happily jump off. For others, this can be a little intimidating.

Here’s a good way to get started manipulating the XML DOM directly – let’s add “Move Up” / “Move Down” buttons to a Repeating Table so you can re-order the items.

First off, let’s build the view:

1. Fire up InfoPath 2003 and start a new blank form
2. Insert a Repeating Table from the Controls task pane
3. Delete the text box in the last column, and add two buttons in that cell instead
4. Pull up the properties on first button and give it the label “5” and the ID “MoveUp”
5. Pull up the properties on second button and give it the label “6” and the ID “MoveDown”

At this point, you’re thinking “5 and 6???”

1. Select both buttons (Click the first, and Ctrl+Click the second)
2. On the Font drop-down on the toolbar, select Marlett. Then take a look at the buttons.

(Sneaky, huh? Glyphs from this font are used by Windows to render all sorts of UI elements like the Minimize/Maximize Window buttons. This is a handy way to avoid having to use images for simple things like arrows.)

Now that we have it looking pretty, let’s add the event handlers for the buttons. We’ll build on the logic from this blog entry to figure out which instance of the buttons was clicked.

1. Pull up the properties on the first button and click Edit Code – paste the following into the editor:

Sub MoveUp_OnClick(eventObj)

Dim oItem, oParent, oPrevious

Set oItem     = eventObj.Source

Set oParent   = oItem.parentNode

Set oPrevious = oItem.previousSibling

If Not ( oPrevious Is Nothing ) Then

oParent.removeChild oItem

oParent.insertBefore oItem, oPrevious

End If

End Sub

The logic here is straightforward:

• Grab the context node of the button (the row of the table, in our case)
• If there is another item before the context node, remove the context node from the tree and re-insert it before the previous node
1. Pull up the properties on the second button and click Edit Code – paste the following into the editor:

Sub MoveDown_OnClick(eventObj)

Dim oItem, oParent, oNext

Set oItem   = eventObj.Source

Set oParent = oItem.parentNode

Set oNext   = oItem.nextSibling

If Not ( oNext Is Nothing ) Then

oParent.removeChild oNext

oParent.insertBefore oNext, oItem

End If

End Sub

The logic here is similar:

• Grab the context node of the button (the row of the table, in our case)
• If there is another node after the context node, remove the it and re-insert it before the context node

Almost done – let’s just use a little Conditional Formatting to disable the buttons when the item is the first or last in the list:

if “The expression” “position() = 1” then Disable this control

if “The expression” “position() = last()” then Disable this control

Now try it out.

As an aside, this was the author’s first foray into VBScript. Although I cut my teeth in Applesoft BASIC I’ve done most of my programming in C-style languages (C, C++, C#, Perl, Java). Did I do anything silly?

• #### Modifying InfoPath manifest.xsf file from script (5/5)

Part 5 of 5: The final function

And the final function is

function FixupSolutionXSN(

inputDirectory,

xsnInputName,

outputDirectory,

xsnOutputName,

serviceURL,

wsdlURL)

{

var XsnInputPath = Combine(inputDirectory, xsnInputName);

var XsfInputPath = Combine(inputDirectory, "manifest.xsf");

var XsfOutputPath = Combine(outputDirectory, "manifest.xsf");

ExtractFilesFromXSN(XsnInputPath, outputDirectory);

FixupXSF(XsfInputPath, XsfOutputPath, serviceURL, wsdlURL);

MakeXSNFromFiles(inputDirectory, "manifest.xsf", outputDirectory, xsnOutputName);

}

Now the gentle reader has free reins to drive the code above to the helpful utility.

Converting the script to managed code would be a good exercise as well.

• #### Auto height for sections

InfoPath forms are all about being dynamic, so it's important that the sections in your form grow and shrink appropriately. For example, if someone deletes an optional section from inside another section, the outer section should shrink accordingly.

Of course, sections will grow/shrink by default after you insert them, but InfoPath will change it to a fixed size if you resize the section, since we don't want to disobey your command to be a specific size. So in the example above, the outer section will stay the same size even when the Notes section isn't there -- it will just have a bunch of white space in its place.

The trick: Use "auto"
If you resized a section by accident and want to return it to the default, just open its properties, switch to the "Size" tab, and type auto for the height. Now it will only be as big as it needs to be and never bigger.

- Ned
• #### Add C# or Visual Basic to your existing form using VSTO

Have you ever created an InfoPath form to later discover that you have to write code in order to accomplish something you need?

If so, you have one of two options:

You can use VSTA to add managed code to your form.  It is included in the Office package, but it is turn off by default.  You must go the Add/Remove Programs and customize Office to install it.

-- OR --

You can use VSTO to add managed code to your form which is what this blog entry is about.

When you create an InfoPath Form Template using Visual Studio 2005, you start with the Design a Form dialog.  On the left you’ll see:

Choosing one of these options will allow you to create a project using an existing form template.  For example, if you wanted to use a form template from a SharePoint site, you would choose the second option.  You can also choose the last option to import an Excel workbook or a Word document as your form template.

If you've selected an existing form template, you will get a message:

If you've selected a form template that already had code behind it, the existing code will be removed from the new form template as well.

VSTO will now create a project based on the form you've selected and you're ready to add code!

- Gary
Software Development Engineer

## Using Office Single Sign-on  with individual mapping

An Office Single Sign-on (SSO) application definition, can be set up in one of three ways:  individual, group, or group using restricted credentials.  An InfoPath form published to the server can use either of the first two.  However, in order to use individual credentials, the SSO database must contain a separate username and password for each user who connects to the form.  A typical server application would check whether the connecting user had credentials in the database, and redirect to a credentials management page when appropriate to allow the user to enter their credentials.  While InfoPath Forms Services does not do this generically for forms that use SSO, it’s possible to implement a solution for an individual form or a set of forms the same way an Office Server application would, by using the Pluggable SSO API.

The general approach is to have users link to an ASP.NET page rather than directly to the form.  The ASP.NET page attempts to get the user’s credentials from the SSO database, and based on the result either redirects to the form or to a credential management page  which allows the user to input their credentials.

Enough talk.  Let’s get our hands dirty.

My code assumes that you have defined an SSO application definition called MyApp and that the application is set up to use individual credentials.  I also assume that that have an administrator-approved form template called myform.xsn activated on the site collection, and that the form uses one or more data connections that reference the MyApp application.

In order to use SSO to make the data connection, you must be using data connection settings in a UDC file on the server.  To add the reference to the MyApp app definition, you add an Authentication element to the UDC file.  The authentication element must be the last subelement of the ConnectionInfo element, and it looks like this:

<udc:Authentication>
<udc:SSO AppId="MyApp" CredentialType="NTLM"></udc:SSO>
</udc:Authentication>

To create the redirector page, the first thing is to add a new ASP.NET page to the root site of your SharePoint server.  Find the home directory of your root site by opening up Internet Services Manager and checking the Home Directory page of the properties page for the web application.  Open this web in Visual Studio and add a new ASP.NET page.  In the properties  for the page, enable session state.  Finally, add a reference to the Microsoft.SharePoint.Portal.SingleSignon namespace.

Once this is done, the new page should look like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SingleSignonRedirector.aspx.cs" Inherits="SingleSignonRedirector" EnableSessionState="True" %>
<%@ Import Namespace="Microsoft.SharePoint.Portal.SingleSignon" %>

Open the code file for the page, and add a using statement for the SingleSignon namespace

using Microsoft.SharePoint.Portal.SingleSignon;

The code itself is relatively straightforward.  Start by using the pluggable API to get a reference to the installed SSO provider.

ISsoProvider provider = SsoProviderFactory.GetSsoProvider();

(this call will fail if no provider is installed, or if the Single Signon service is not running)

Your page will run under the credentials of the user attempting to access the form, so when you call GetCredentials, SSO will return a credential for that user, or throw SingleSignonCredsNotFoundException if the credential does not exist.

try
{
SsoCredentials credentials = provider.GetCredentials("MyApp");
}
catch (SingleSignonCredsNotFoundException)

In the event that the credentials are not found, you can get the URL of the credentials management page for the installed provider.

Uri CredentialsManagementUrl = provider.GetCredentialManagementURL("MyApp");

Now, at this point you could simply redirect to the credentials management URL.  However, you would miss part of the magic of the credentials management page.  The credentials management page supplied with the Office single Sign-on provider will redirect back to the referring page once the user has entered valid credentials.  I chose to handle this by presenting a link to the user to allow them to click through to the credentials management page.

Response.Write("<P>Before you can access this form, you must enter credentials to access backend data.</P>");
Response.End();

An alternate approach could be to add the HTTP referer header to the response before performing a redirect.  Either way, once the user has entered their credentials, the redirector page will be called again.  This time the GetCredentials call will succeed, and the page will redirect on to the form.

Here’s the complete code-behind for the page:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Microsoft.SharePoint.Portal.SingleSignon;

public partial class SingleSignonRedirector : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ISsoProvider provider = SsoProviderFactory.GetSsoProvider();
try
{
SsoCredentials credentials = provider.GetCredentials("MyApp");
}
catch (SingleSignonCredsNotFoundException)
{
Uri CredentialsManagementUrl = provider.GetCredentialManagementURL("MyApp");
Response.Write("<P>Before you can access this form, you must enter credentials to access backend data.</P>");
Response.End();
}
catch (Exception ex)
{
Response.Write("<P>Single Sign-on returned an error:  " + ex.Message + "</P>");
Response.End();
}

// Good to go - on to the form
Response.Redirect( "http://myserver/formservertemplates/myform.xsn?openin=browser" );

}
}

Getting jiggy with it
For a real-world application, there are a few more things I might do to this page to round out the implementation.  Depending on the needs of the specific application, one or more of the following might apply:

• Loop through multiple Application IDs to allow the user to enter credentials for each
• Attempt to log on the user using the SSO credentials to verify that the credentials are valid and have not expired
• Use this code in a page which hosts the form in question using the XmlformView control
• Create a generic page which takes the URL to the form and the Application ID as query parameters
With a little bit of ingenuity, you can use this approach to create a seamless end-to-end experience to satisfy any scenario.

In my next and final post in this series, I'll talk about how to use a web service proxy for authentication. Stay tuned!

- Nick
Program Manager
• #### InfoPath Trick to Localize a form in a single view

TRICK: Localized form in a single view

Applies to: Microsoft Office InfoPath 2003 SP1

Need the same form in many languages?  Here’s a trick that’s easier than multiple views.

Summary

By taking advantage of new SP1 features, there’s a simple way to create a multi-language view without duplicating bindings.

I have used a secondary data source with read-only borderless fields as labels for the view.  This secondary data source is populated by an XML File Data Connection that grabs a file in the LabelsLanguage form library.  This form lib populates a drop-dom, changes of this update the aux-dom and refresh the view.

There are 2 buttons for adding new languages and editing the current labels of the form.  These pop up a second solution.  To add a new language, just fill out the form and submit.  Look at one of the existing languages for examples.  If you see a typo in your language, feel free to correct it and save.

To work with button labels, manually update the view using xsl:value-of elements.  Otherwise, use the workaround that I have in the screenshot.

Known issues:

• If you update a language on the fly, you need to force IE to always update the cache so you will get the drop-down changes.
• Some flashing when changing the language.

Example

Here’s a sample of what it might look like:

Form Code

{
if (e.IsUndoRedo) return;
if (e.Operation.ToUpper() == "DELETE") return; //handle double notifications

// Generate the new file name from the drop-down
string strFileName = (string)e.NewValue; //from dropdown english.xml
string strCurrentUrl = xfaLabels.FileURL; //from adapter http://server/site/francais.xml
string strBaseUrl = strCurrentUrl.Substring(0,strCurrentUrl.LastIndexOf("/")); // http://server/site
string strCurrentFileName = strCurrentUrl.Substring(strCurrentUrl.LastIndexOf("/")); // francais.xml
string strNewUrl = strBaseUrl + "/" + strFileName;          // http://server/site/english.xml
xfaLabels.FileURL = strNewUrl;

// the drop-down refreshes everything
xfaLabels.Query();
}

{
string strLanguagesFormUrl = "http://your-forms-url/template.xsn";
thisApplication.XDocuments.NewFromSolution(strLanguagesFormUrl);
}

public void EditLabels(DocActionEvent e)
{
thisApplication.XDocuments.Open(xfaLabels.FileURL, 1);
}

• #### Philo's WebLog post on "Why Smart Clients?"

Why Smart Clients? was posted yesterday and provides a nice perspective of the benefits of having such a smart client like InfoPath.

• #### Understanding the InfoPath SP1 Deployment and Security Model – An Introduction

A common question that was asked when people started using the initial InfoPath release was, “How can I distribute a form template to other people through email?”  In InfoPath V1, this was difficult because once you saved or published a form template to a location, it was ‘sited’ to that location.  If it was moved from that location, it would not open in the InfoPath Editor.

In the InfoPath Service Pack 1 release, it is now possible for form templates to be opened from locations other than their published location.  There is also a ‘Send Form as Attachment’ option under the File menu which attaches your form template to an Outlook mail message for distribution.  However, for security reasons, there are still limitations on what kinds of form templates can be opened and from what locations.  The following is a guide to understanding the InfoPath SP1 Deployment and Security Model:

Form Template Security Level

Each Form Template made in InfoPath SP1 has one of three security levels specified; Restricted, Domain, or Full Trust.  This setting is determined automatically by default, but can be set manually, if desired.

NOTE:  To access this setting in the Designer, navigate to Tools | Form Options à Security Tab.

Restricted – The form template does not allow any access outside of the form

Domain – The form template allows access outside of the form, but only within the domain of the form template

Full Trust – The form template can access files and settings on the local computer

The Full Trust security level can only be set manually by the user for installed templates or certificate-signed templates.  The maximum trust level that can be set automatically by InfoPath is Domain.

All new blank form templates (except for Managed Code solutions) start out at the Restricted security level.  As you build the form, adding any of the following will automatically raise the security level to Domain:

• Script
• Web Service Query or Submit Adapter
• SharePoint Query or Submit Adapter
• Query to linked XML file
• HTTP Submit
• ActiveX Control
• Roles
• DLL Resource File
• HWS
• Rule that opens a new document

Opening the Form Templates in the InfoPath SP1 Editor

The reason to make a distinction between Restricted and Domain security was to allow for form templates without script or data connections to be opened from anywhere.  Therefore, email deployment of restricted form templates in SP1 is easy, just send out the form template and it can be opened either from the Outlook mail itself or from wherever the recipient saves it.

With Domain form templates, some of the same security restrictions from v1 still exist, but SP1 allows for some added functionality.  Domain form templates still require that they be opened from their published location.  However, by using the Send Form as Attachment option in the file menu, a Domain form template can be mailed out as an attachment.  This attachment, when received and opened, functions as a link to the actual published location.  The form template at that publish location is what actually gets opened in the InfoPath Editor, not the one that was clicked on.  At that point as well, the published form template is copied locally and will appear as a selection in the Fill Out a Form dialog every time you launch InfoPath.

Future Considerations

This posting is meant as an introduction and does not cover all aspects of Deployment and Security.  If there are any specific questions, please respond via feedback to this article and I will follow up with further entries that will address more specific functionalities and scenarios.

• #### Decoding the InfoPath picture format (also Ink Picture)

InfoPath provides two controls which saves pictures inside the XML form (rather than linking to it). When trying to process this XML file outside of InfoPath, you will need to translate the data back into the image binary. InfoPath picture control data and ink picture control data is stored in the XML as base64 encoded data. You will need to decode the base64 picture into binary before it is usable.

Below is a code sample in C# that will do it:

byte[] image = Convert.FromBase64String( s );
MemoryStream memStr = new MemoryStream();
memStr.Write( image, 0, image.Length );
Image img = Image.FromStream( memStr );
img.Save( filename );

• #### Modifying InfoPath manifest.xsf file from script (2/5)

Part 2 of 5: Unpacking the XSN

To unpack XSN one should use extract.exe utility. It can be found in the %SystemRoot%\system32 directory or in the Microsoft Cabinet Software Development Kit. For the command usage details just run “extract /?”.

In this part we will also introduce several auxiliary functions that will be extensively used throughout the entire discussion topic.

var ExtractExeLocation = "%SystemRoot%\\SYSTEM32";

var ExtractExe = Combine(ExtractExeLocation, "extract.exe");

function Combine(dir, file)

{

return dir + "\\" + file ;

}

function QuoteStr(string)

{

return ("\"" + string + "\"");

}

function Exec(string, flagWait)

{

if (flagWait == null)

flagWait = true;

var WScriptShell = WScript.CreateObject("WScript.Shell");

return WScriptShell.Run(string, 0, flagWait);

}

function ExtractFilesFromXSN(xsnInputPath, outputDirectory)

{

var Parameters;

// add the location to place extracted files,

// a flag "/Y" that prevents prompting before overwriting

// an existing file, and a flag "/E" that orders to

// extract all files

if (outputDirectory != null)

Parameters = " /Y /E /L " + QuoteStr(outputDirectory);

Exec(QuoteStr(ExtractExe)

+ Parameters

+ " " + QuoteStr(xsnInputPath), true);

}

Now we have a tool to unpack XSN. All of the InfoPath form template files are accessible for changing. In the next part of the series we will be modifying the manifest itself.

Page 6 of 12 (298 items) «45678»