Microsoft InfoPath 2010
The official blog of the Microsoft InfoPath team

  • Microsoft InfoPath 2010

    Cascading Dropdowns in Browser Forms

    • 29 Comments
    If you are building an InfoPath client-only solution and you need to filter drop-down list boxes, you can simply use the “Filter Data” feature when you set the Entries property for the control. However, since filters are not supported in browser-compatible form templates, how can you accomplish the same functionality?
     
    This is where .NET web services can “save the day!” By creating web methods that accept parameters, you can add those web methods as data connections and then pass the selected value from one drop-down list box to the appropriate data connection “queryField”. Once the queryField has been set, simply execute that data connection to retrieve the associated values.
     
    To setup this sample, you will need to have access to the SQL Server Northwind sample database and Visual Studio installed on your server.
     
    First, let’s create the web service and the two web methods we will use in this sample:
     
    Step 1: Open the appropriate web site
     
    1. Launch Visual Studio
    2. From the File menu, select Open and choose Web Site
    3. Select File System and then navigate to: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS
     
    NOTE: By choosing to open the LAYOUTS folder, your web service will be available from all provisioned sites. If you want the web service only to be available from a specific site (i.e. the default site) you would want to open: C:\Inetpub\wwwroot\wss\VirtualDirectories\80
     
    1. Click Open
    2. In the Solution Explorer, right-click on the web site and choose New Folder
     
     
    1. Rename this folder to: WebServices
    2. Because you may have multiple web services, let’s add a sub folder here that is specific to our web service:
      1. Right-click on WebServices and choose New Folder
      2. Rename this folder to: NorthwindTables
     
     
    Step 2: Create the web service
     
    1. Right-click on NorthwindTables and choose Add New Item
    2. From the Visual Studio installed templates list choose Web Service
    3. In the Name box, rename this to: NorthwindTable.asmx
     
     
    1. Uncheck the option “Place code in a separate file” and click Add
     
     
    Step 3: Add the web methods
     
    NOTE: For this sample, it is assumed the SQL Server database is installed on the same Microsoft Office SharePoint Server. 
     
    1. Add the following “using” declarations at the top of your code page: 

    using
    System.Data;
    using System.Data.SqlClient;
     
    1. Add the following web method to retrieve the CustomerID values from the Customers table in the Northwind database:
     
    [WebMethod]
    public DataSet GetCustomers() {
                // Create a SQL connection to the Northwind sample database
                SqlConnection cn = new SqlConnection("Data Source=(local);Integrated Security=SSPI;Initial Catalog=Northwind");
     
                // Create data adapter object passing it the SELECT
                // statement to retrieve the customer ID values
                SqlDataAdapter da = new SqlDataAdapter("SELECT Customers.CustomerID FROM Customers Order By CustomerID", cn);
     
                // Create a dataset object to store the data
                DataSet ds = new DataSet();
     
                // Open the connection
                cn.Open();
     
                // Fill the dataset
                da.Fill(ds, "Customers");
     
                // Clean up
                cn.Close();
                cn = null;
                da = null;
                
                return ds;
                }
     
    1. Add the following web method to retrieve the associated orders for the selected customer:

    [WebMethod]
    public DataSet GetOrdersForSelectedCustomer(string strCustID) {
                // Create a SQL connection to the Northwind sample database
                SqlConnection cn = new SqlConnection("Data Source=(local);Integrated Security=SSPI;Initial Catalog=Northwind");
     
                // Create a string variable for the modified SQL statement
                string strOrdersSQL = "";
     
                // Create a string variable for the default SQL statement
                string strOrdersOrigSQL = "SELECT * FROM Orders";
     
                // Some of the customer ID values contain apostrophe's - we need
                // to replace them with two single quotation marks so that all
                // single quotation marks in the CustomerID are parsed correctly.
                strCustID = strCustID.Replace("'", "''");
     
                // Concatenate the default SQL statement with the "Where" clause
                // and add an OrderBy clause
                strOrdersSQL = strOrdersOrigSQL + " Where CustomerID Like '%" + strCustID + "%' Order By OrderID";
     
                // Create data adapter object passing it the SELECT statement
                // to retrieve the OrderID values
                SqlDataAdapter daOrders = new SqlDataAdapter(strOrdersSQL, cn);
     
                // Create a dataset object to store the data
                DataSet Ds = new DataSet();
     
                // Open the connection
                cn.Open();
     
                // Fill the DataSet
                daOrders.Fill(Ds, "Orders");
     
                // Clean up
                cn.Close();
                cn = null;
                daOrders = null;
                     
                return Ds;
    }
     
    1. Build and save the project
     
     
    Step 4: Test the web methods
     
    NOTE: The Identity account of the Application Pool for the web site where this web service is published will need to have access to the SQL Server database.
     
    1. Open a browser and navigate to: http://<server>/_layouts/WebServices/NorthwindTables/NorthwindTables.asmx (replace <server> with the name of your server)
    2. You should see the two web methods created above along with the default HelloWorld web method:
     
     
    1. Click the GetCustomers link and then click Invoke – this should return a list of the CustomerID values
    2. Click the GetOrdersForSelectedCustomer link, in the strCustID box enter: BERGS and then click Invoke – this should return a list of only those OrderID values for BERGS
     
     
    Step 5: Create the InfoPath form
     
    1. Design a new, blank, browser-compatible InfoPath Form Template
    2. Add a drop-down list box to the view and modify the name to: SelectCustomer
    3. Add another drop-down list box to the view and modify the name to: SelectOrder
     
     
     
    1. Add a new “receive data” data connection to the NorthwindTables web service for each of the web methods created above as follows:
      1. GetCustomers:
        • Enable the option “Automatically retrieve data when the form is opened”
      2. GetOrdersForSelectedCustomer:
        • Use ALFKI as the sample value for the strCustID parameter when prompted in the Data Connection Wizard
        • Uncheck the option “Automatically retrieve data when the form is opened”
    2. Set the Data source for SelectCustomer to the GetCustomers data connection and use the CustomerID field for both the Value and Display name properties
    3. Set the Data source for SelectOrder to the GetOrdersForSelectedCustomer data connection and use the OrderID field for both the Value and Display name properties
    4. Create a Rule on SelectCustomer with the following actions:
      1. Set a field’s value: Set the SelectOrder field to nothing (e.g. leave the Value blank)
      2. Set a field’s value: Set the parameter value (strCustID) for the GetOrdersForSelectedCustomer data connection to the SelectCustomer field
      3. Query the GetOrdersForSelectedCustomer data connection
     
     
    1. Save the form locally as FilteredDrop-downs_IPFS.XSN
     
     
    Step 6: Publish the form
     
    1. Publish the form to a server running InfoPath Form Services
    2. Navigate to the form library where the form was published and click the New button
    3. From SelectCustomer choose BERGS
    4. Click SelectOrder – only those orders for BERGS are displayed
    5. Select a different customer – notice the orders have also changed
     
    Scott Heim
    Support Engineer
  • Microsoft InfoPath 2010

    Do it anyway: Submitting with Data Validation errors

    • 5 Comments
    When building a workflow solution using InfoPath, it is often necessary to enforce data validation for some, but not all users. For example, in a simple expense report workflow, Employee->Manager->Accounting, the manager may be required to specify the cost category. The employee, however, can't provide this data. This means that setting the "cannot be blank" property for the costCategory field in the InfoPath form will not be enough to make this work. In this article, we will explore a technique that will let you use powerful InfoPath data validation capabilities to enforce this business logic correctly.
     
    You may have seen a different incarnation of the same problem - "if only I could submit the form with data validation errors...". If so, read on.
     
    1. Create a node in your data source that remembers the role of the current user; let’s call that node userRole. Create rules or code to get that node populated on load of the form.

      Trick 1 - acquiring user role. To set the value of a node to the current user role in rules, use the XPath expression xdXDocument:get-Role().

      Trick 2 - acquiring Active Directory username.  If you are using InfoPath 2007, you can get to the username of the current user through the built-in userName function. In InfoPath 2003, the easiest way to accomplish this is to write a simple whoAmI web service (here is a sample implementation), and plug it in to your form template through a secondary data connection.

    2. Setup data validation logic on the costCategory field by using the Data Validation dialog (not through the “cannot be blank” shortcut in the properties dialog).

    3. Add a new "logical and” clause to the data validation condition. This clause will check if the userRole actually requires the field to be filled out. The entire data validation condition will evaluate to false if the userRole doesn't have this requirement, and the error message will not be shown:
     
    This technique will work in both InfoPath 2003 and InfoPath 2007, and it is supported in browser-enabled form templates.
     
    Alex Weinstein
    Program Manager
  • Microsoft InfoPath 2010

    Where do UDC files come from?

    • 11 Comments
    Where do UDC files come from? - I knew you’d ask. (For those of you who are wondering what a UDC file is, you should go read my post entitled "Making data connections work in browser forms.")
     
    There are a couple of ways to go about it. UDC files are just xml files with a specific namespace and schema, so once you have a few examples you can probably get around handily with notepad and cut and paste. However, we’ve made it easier than that with the new Convert functionality on the Manage Data Connections dialog. (For those intrepid souls who prefer the notepad route, a schema reference is being prepared for publication.)
     
    If you start out by designing your data connection the way you normally would, you can then use the Convert button to change the connection from settings in the form template to settings in a data connection file. (In fact, you can open any existing form template in InfoPath 2007 and convert existing data connections the same way.)
     
    To start with, make sure you have write permissions to a data connection library (henceforth "DCL") on the Microsoft Office SharePoint 2007 server you’re going to publish your form to. Then, using InfoPath 2007 Beta 2 or later, create your data connection or open a form template with an existing data connection. Make sure the connection is to a source supported by UDC. (E-mail connections, connections to a Microsoft Access database, or connections to an XML file in the form template cannot be converted to UDC connections.)
     
    Here’s the data connections dialog showing a few connections I threw together (you can get to this dialog off of the "tools" menu in InfoPath design mode):
     
     
    Click the Convert button and specify the path to your data connection library. If you click "Browse...", InfoPath will suggest a filename based on the name you gave the data connection when it was created.
     
     
    If you choose a data connection file that already exists, InfoPath will use the settings in the file you chose - don’t expect it to overwrite the original file with new settings. This could have unexpected results if the file that’s already in the library is a different connection type or returns data that does not conform to the schema your form template expects.
     
    For most cases, you want to leave the default connection link option. Choosing "centrally managed connection library" will cause InfoPath and Forms Services to look for the UDC file in the "Manage data connection files" library in SharePoint central admin. This is fine, but it means that you need to copy the file from the DCL where you created it to that location before you can use it. This presumes you have access to SharePoint Central Admin. See my last blog post entitled "Making data connections work in browser forms" for more information on this option.
     
    Once you click "OK" on this dialog, your UDC file will be created and saved to the location you specified, and the connection in the form template will be modified to retrieve settings from the UDC file rather than from the form template.
     
    NOTE: There’s a known issue in the Beta 2 release where you will see an "invalid URL" dialog at this point. This is benign and is no longer seen in the technical refresh.
     
    You now have a UDC file in your DCL, but you’re not quite done. By default, a DCL will require content approval before anyone other than the file’s owner can use the UDC file you uploaded. Unless the content approval requirement has been removed, a site administrator or someone else with the content approval right will need to set the file’s status to "approved."
     
    Adding Authentication
    InfoPath does not automatically configure server-only authentication options for you. However, when creating a UDC file, InfoPath automatically creates an authentication block within the UDC file that is preconfigured to use Office Single Sign-on. In order to use this authentication option, you’ll need to uncomment the authentication block within the file and add both the SSO application ID and the CredentialType. Most of the time, you’ll want to use the SSO credential to log onto Windows, for which you’ll need to specify "NTLM" as the CredentialType. The full list of possible credential types is as follows:
     
    Value
    Description
    Sql
    Credentials will be embedded in a database connection string for authentication against a SQL server.
    NTLM
    Credentials will be used to impersonate a Windows user
    Kerberos
    Credentials will be used to impersonate a Windows user using Kerberos
    CD
    The username will be used to impersonate a Windows user using Constrained delegation
    Basic
    Credentials will be used to perform HTTP Basic authentication
    Digest
    Credentials will be used to perform HTTP Digest authentication
     
    Reusing existing UDC files
    Once you’ve created your UDC file, you may want to use the same connection for other form templates. Among other things, this has the benefit of sharing settings for multiple forms in a common location. Changing the settings in the UDC file will cause all of the related forms to pick up the changes the next time they are used.
     
    There are several places in InfoPath where we expose the ability to re-use data connection settings exposed as UDC files in a data connection library. Here are a few examples:
     
     
     
     
    All of these entry points lead to this dialog:
     
     
    When you specify one or more SharePoint sites to search, this dialog allows you to browse available UDC files containing in DCLs on those sites. Based on the context, this dialog is filtered to show only applicable connections (for example, if you start from the "Design a form" dialog, this dialog will only show Web service and database connections).
     
    Once you’ve specified the UDC file to use, you may need to specify some properties for the connection that are not contained in the file (for example, for a SharePoint list connection, you’ll be asked to specify which columns to include in the data source), but otherwise, you’re done.
     
    - Nick Dallett
    Program Manager
  • Microsoft InfoPath 2010

    Data Connections in Browser Forms

    • 17 Comments
    A while back, I wrote a series of 3 blog posts about authentication that was targeted at advanced enterprise-level scenarios involving multi-tier delegation of credentials for data connections on the server. However, I never took the time to cover the basic scenarios around getting basic data connections to work on the server. This post will answer the question "how do I get my data connection to work on the server". Cart, meet horse.
     
    When we started defining the server experience for InfoPath forms, one of the guiding principles we espoused was "design-once." Meaning, provided you stick within the subset of functionality supported on the server, you could design a form once and it would run in InfoPath and in Forms Services. That is basically true for data connections, but there are two special considerations that differ significantly when moving to the server, namely
    • Authorization to perform cross-domain connections
    • Multi-tier authentication
    The cross-domain issue, server edition
    Short version:
    You can’t make a cross-domain connection from a domain security browser form unless your data connection uses a UDC file.  Period.
     
    Long version:
    InfoPath has three security modes, which we refer to as restricted (AKA "super-sandbox"), domain, and full-trust.  Restricted form templates don’t run on the server.  Full-trust form templates are allowed to do whatever and consequently need to be administrator-approved in order to run server-side.  Domain trust form templates constitute the vast majority of form templates in the enterprise, and roughly follow the Internet Explorer security model which dictates that by default, the user must approve any attempt to access resources that come from a different domain or Zone.  So, if you have a form template running on http://myserver/, and it tries to connect to a web service on http://yourserver/, InfoPath will prompt you before trying the connection.
     
    Works great in InfoPath, but when you run a form in the browser, you may be running server-side business logic.  That business logic may want to execute a data query.  Because HTTP is a stateless protocol, Forms Services can’t halt execution of a server-side process and return to the browser in order to ask you for permission to continue.  Additionally, the user in this case may not be the right person to own the decision about whether the cross-domain connection can take place.  So, this decision is placed instead in the hands of the server administrator who owns security around the form template.  Depending on whether the form is administrator-approved or just published to a document library by Joe User, this ownership falls on the farm administrator (I call her Julie) or the site collection administrator (henceforth known as Bob).
     
    The technology which allows Julie and Bob to determine whether forms can make cross-domain connections involves a system of checks and balances.  Central to this system is a data connection settings file in the Universal Data Connection V2 format, called a UDC file.  Bob’s UDC files live in a special type of document library called a Data Connection Library, or DCL.  Julie’s UDC files live in the Microsoft Office SharePoint Server configuration database, and are managed via the "Manage Data Connection Files" page in the Application Management section of SharePoint Central Administration (I tend to refer to this as "the store").
     
     
    The basic premise behind UDC files is that in InfoPath 2007 your data connection settings can live outside of the form template in one of these files, and both InfoPath and Forms Services will retrieve the current connection settings from this file at runtime before making the connection.  The UDC file itself is retrieved from a URL relative to the root of the site collection where the form was opened.  This enables lots of cool functionality - for example, you can now share settings across multiple forms and change them once when you move your data source. 
     
     
     
    You can also pre-deploy test and production versions of your data connection settings to your staging and production environments so that you don’t need to update the form template with new data connection settings when you go live. 
     
     
    For the purposes of this discussion the key takeaway is that a domain security form running in the browser will never make a cross-domain data connection unless those connection settings come from a UDC file.
    In other words, you can’t make a cross-domain connection from a domain security browser form unless your data connection uses a UDC file.  Period.
     
    Why is this more secure?  Well, if Bob is a good administrator, he controls access to Data Connection Libraries on his site collection.  A DCL requires content approval by default, and while members of the site with Contributor access can write files to the library, nobody but the owner of the file can use the file from InfoPath unless a content approver has approved the file.  By default, all members with Designer permissions have the Content Approval right.  In short, Bob can set up the site collection such that only people that he designates can approve UDC files.  Therefore, forms on Bob’s site collection can only make connections outside the farm unless he approves the connection first.
     
    Julie’s central store is more secure - only users with access to SharePoint Central Administration can modify those files.  Furthermore, by default only the server object model can access files in the store.  In order to make these files accessible to web clients such as InfoPath, the "web accessible" flag must be set.  Otherwise, the files can be used from browser forms only.
     
     
    Finally, if Julie wants to have complete control over cross-domain connections for the farm, she can turn off the ability for user form templates to make cross-domain connections at all (in fact, these are disabled in a default install).  When cross-domain connections are disabled for the farm, even connections that use settings from a UDC file can’t make cross-domain connections.
     
    Solving multi-tier authentication issues
    Once your form is allowed to make cross-domain connections, you’ll need to deal with getting access to the data.  If your data lives on a different computer than your Forms Services site, this means figuring out an alternative set of credentials for data access.  I’ve covered why this is true, and the various options for accomplishing this task, in a series of posts called "Advanced server-side authentication for data connections," but I left out one useful prototyping trick.  Consider the following UDC authentication block:
     
    <udc:Authentication>
           <udc:UseExplicit CredentialType="NTLM">
                  <udc:UserId>myusername</udc:UserId>
                  <udc:Password>mypassword</udc:Password>
           </udc:UseExplicit>
    </udc:Authentication>
     
    The UseExplicit element allows you to specify a username and password in plaintext.  When this is present, Forms Services will impersonate the specified user using the supplied credentials.  This is a great tool for prototyping - you can see immediately whether your connection can be made given valid credentials before you go to the trouble of setting up Office Single Sign-on.  However, I cannot stress enough that this is for prototyping only.  Because  the UDC file is in clear text and is accessible to anyone with read permission on the library, this puts a windows username and password in clear text on the network, which is bad-bad-bad.  You’ve been warned.
     
    Whatever Julie wants, Julie gets
    The "Manage data connection files" page (AKA "the store") gives Julie a great deal of power over the use of data connections in administrator-approved form templates.  Furthermore, Julie also has a great deal of control over what Bob’s users can  do.  The following defaults can only be modified on the Configure forms services page:
    • User form templates cannot make cross-domain connections (not even with a UDC files)
    • User form templates cannot use authentication embedded in a database connection string. 
    • User form templates cannot use the authentication section of the UDC file 
    • User form templates can use credentialType BASIC or DIGEST only if the connection is made using SSL.
    • User form templates cannot make cross-domain connections (not even with a UDC files)
    • User form templates cannot use authentication embedded in a database connection string.
    • User form templates cannot use the authentication section of the UDC file
    • User form templates can use credentialType BASIC or DIGEST only if the connection is made using SSL.
     
    The following default setting can only be modified on the Configure Web Service Proxy page:
    • User form templates cannot use the Web service proxy
     
    What’s next?
    Now that you’re motivated to use UDC files to enable data connections on the server, you’ll need to know how to create them and how to re-use them.  I’ll tackle that topic in a future post.
     
    - Nick Dallett
    Program Manager
  • Microsoft InfoPath 2010

    Protecting Sensitive Data

    • 9 Comments
    Frequently, we find developers using InfoPath as a platform for developing solutions that manipulate sensitive data, may it be financial data, patient records, or performance review forms. This article shares tips on protecting such data.
     
    First and foremost, you must know that an InfoPath form is a plain-text XML file. A malicious user can read it through Notepad or other text editor, circumventing any InfoPath authentication logic. So if a user has read access to an InfoPath XML form, anything stored in that XML file can be read. Information Rights Management in InfoPath 2007 allows storing encrypted XML; we'll talk more about it below.
     
    Also remember that an InfoPath form template (.xsn file) is just a CAB archive, containing plain-text files. These files store all client-side form logic. Information Rights Management allows you to encrypt form templates in InfoPath 2007, see more about it below.
     
    Like with any other client-server application development platform, you can never trust the logic that happens on the client. InfoPath uses the form template to store all form logic; if the user has access to the form template (and they must in order to be able to open any form based on that form template), they can create a hacked version of the template, circumventing any restrictions that the original form author put in place.
     
    This means that authentication and authorization performed on the client can't be trusted; calculations and data validation have to be re-done on the server. Here is an example of how this strategy can be realized for a simple record-keeping application:
     
    • Do not store sensitive data in the XML file; instead, store keys in the XML file, and perform queries on load that populate the rest of the data by using a database/web service. If the user is unauthorized (as determined by the server-side logic), return an empty dataset. You can even detect such condition on the client and show a friendly error message.
    • On submit, send the data to a web service and redo all non-schema validations on the server side. For example, if employees should not be able to submit expense reports above $100 without specifying an approver, have your web service process the dataset and verify that this condition is satisfied. 
     
    It is always a good idea to restrict access to a production form template by assigning read-only permissions to form users, write access to form maintenance staff, and no access to everyone else. This can be done by using permission features of the SharePoint Server or file shares. Even if you install form templates to the users' machines via a logon script, you can still control access to the .xsn file - provided the user is not running as an administrator, you can set their access to the template file to read-only.
     
    You may want to enable the protection feature for production form templates:
     
     
    However, remember that this protection feature is for recommendations only, it is not intended as a security mechanism. This will show the user a nice error message if they accidentally try to open the template in the Design mode, but won't defend the form template against a malicious user.
     
    Information Rights Management, or IRM, is a new feature for InfoPath 2007; some of you may already be familiar with the concepts from the other apps in the Office 2003 release. IRM allows the form author to protect both the form template and forms based on the template; IRM infrastructure must be in place in the organization to make this possible. Briefly, IRM is a way to encrypt both form templates and forms, allowing form author to specify who can access the template and suggest default rights for forms based on the template:
     
     
    Note that IRM is an InfoPath client-only feature, and it will not work in browser-enabled form templates.
     
    Alex Weinstein
    Program Manager
  • Microsoft InfoPath 2010

    Dynamic Pictures

    • 6 Comments
    When designing a feature-rich InfoPath form template, it is sometimes necessary to provide a dynamic image in response to user action. InfoPath picture control hides treasures that will help you satisfy such a requirement. In this article, we will explore a technique that allows you to make this happen without writing any code.
     
    Here is our scenario: build a hardware order form for the telecommunications department. In the form, we would like to let the user choose the phone that they want to order, and show them a picture of the phone as soon as they select it.
     
     
    The following steps will make this possible:
     
    1. Place pictures of available phones in a shared location; let's call it http://mysite/phones/photos/. Pictures are named according to phone ID's - for example, 1.jpg, 2.jpg, 3.jpg, etc.

    2. Insert a picture control. When you do so, InfoPath will ask whether you want the picture to be included into the form, or if you want it to be linked. Choose the second option.
    3. Take a look at the node that was just inserted into your data source by going to View | Data Source. Let’s call the new node hyperlinkDataSource; it’s a node with data type "hyperlink".

    4. Insert a text box that’s also bound to hyperlinkDataSource.

    5. Preview the form. Use the picture control to attach the image. Observe how the path in the text box changes to reflect the path of the image you just attached. Try changing the value of the text box to point to a different picture. Note how the picture control displays the new picture when you tab out of the text box.

      Now, we want this step to happen programmatically, when the user selects the phone from the dropdown of available phones.

    6. Create a phone picker dropdown; labels in the dropdown will show phone names, and values will contain phone ID's that correspond to file names we used in step 1. The simplest way to do this is to enter the items manually; don't forget to include the default "pick a phone" item.




    If you want to get fancy, you can use a secondary data source - web service - to provide the list of available phones.

    1. Create a rule on the phonePicker node: set the value of hyperlinkDataSource to

      concat("http://mysites/phones/photos/", phonePicker, ".jpg")

    2. Go to control properties for the new picture control; uncheck the “Allow users to browse for new pictures” property.

    We're done! Preview the form and try selecting a few phones from the dropdown.
     
    Picture control is available in both InfoPath 2003 and 2007, however it is not supported in browser-enabled form templates.
     
    Alex Weinstein
    Program Manager
  • Microsoft InfoPath 2010

    Save the Date! Using Horizontal Repeating Sections

    • 5 Comments
    InfoPath 2007 introduces a new flavor of the repeating section control - horizontal repeating section. It is useful when you want to present or edit repeating data in a structured format. When new items are added, they show up side-by-side with the existing items instead of one on top of the other.
     
    Horizontal repeating section is a new building block for layouts. In my previous post about horizontal repeating tables, we discussed how a horizontal repeating table is a combination of a horizontal repeating section and layout tables. You can make your own new layouts by using this new control.
     
    For example, one cool use of a horizontal repeating section is a "calendar" - style form:
     
    Play with it!
    Download the form template and try a few things (requires InfoPath 2007, and save it to your computer before opening it):
    1. Switch to a different month by using a dropdown on top of the form.
    2. Add a note for a day.
    3. Add a note with an exclamation sign (i.e. "presentation!") - notice the day turning red.
    4. Switch views to the summary view, and observe all appointments as a flat list.
    5. Open the form template in design view, and view its logic by going to Tools | Logic Inspector.
     
    How it's done
    In this form, each day in the calendar is displayed by using a horizontal repeating section; only the header ("Monday, Tuesday, Wednesday…") is static. To accomplish this, we are using several powerful tricks:
     
    1. Calendar generation is completely dynamic. To generate a view of a different month, we are setting the following fields in the form under myFields/currentMonth:
      • firstDay [date field in XML format (YYYY-MM-DD); set to the first day of the month that you want to view the calendar for - i.e. for May 2007, set to "2007-05-01"]
      • numberOfDays [integer; number of days in the month that you want to present; i.e. for May 2007, set to "31"]
      • mondayOffset [integer; weekday of first day of the month; Sunday=0, Monday = 1, Tuesday = 2, etc. I.e. for May 2007 that starts on Tuesday, set to "2"]

      Note that if you wanted to extend this calendar to show additional months, you could do so by adding rules to set these parameters for different months. It's also easy to move this logic to a web service or form code - thus eliminating the need to maintain a static list of months.
       
    2. Horizontal Repeating Sections wrap when placed inside a table. The wrapping point is determined by table width. This allows us to set up a 7-day-long week.

    3. Conditional formatting works just as expected on horizontal repeating sections. This allows us to highlight today's date, set red background for days marked with an exclamation sign, and set correct background color for weekends.

    4. Default values help us create a necessary number of instances of the horizontal repeating section to cover for the longest month, even if it starts on Saturday. We need 6 instances to cover for "blank" days before the first day of the month, plus a maximum of 31 days in a month = 37 instances. To accomplish this, you can follow the technique from this article.

    5. Rules provide a mechanism for month selection: when a month is selected from the dropdown on top of the form, correct values are set for nodes under myFields/currentMonth.
     
    Of course, there are many uses beyond a calendar, otherwise we would have just built a calendar control, but we couldn't resist sharing this example because it shows off so many tricks.
     
    Alex Weinstein
    Program Manager
  • Microsoft InfoPath 2010

    One-to-Many Relationships on Database Connections

    • 9 Comments
    There have been a few questions about how the main database submit data connection works with related tables.  This is an FYI to clear up some of those issues, as I don't think this information ever made it public!
     
    At least one of the relationships for every pair of related tables must include the left-hand table's primary key (PK) (where A is the left-hand table in "A relates to B on A.ID, B.ID").  Without this stipulation, there may be many records in table A that map to one record in table B along the defined relationship.
     
    Note also that unique indexes and unique constraints allow nulls, so the primary key must be used in at least one relationship (they don't allow nulls).  Basically, InfoPath enumerates the records to be updated according to the primary key.  This way, the data inserted into the database is well-defined.
     
    What that boils down to is this:
    • Sufficient relationships:
      • PK --> Non-unique,  Unique, or PK
    • Insufficient relationships (assuming a sufficient relationship hasn't already been defined):
      • Non-Unique --> Non-unique,  Unique, or PK
      • Unique --> Non-unique,  Unique, or PK
     
     
    Once you've defined one sufficient relationship (as listed above), then you can define any other additional relationships that you want (they don't have to follow my rules listed above).
     
    - Forrest
    Software Development Engineer in Test
  • Microsoft InfoPath 2010

    Enforcing unique values in a repeating list

    • 3 Comments
    Have you ever created a form which allows the user to choose items from a list and you wanted to make sure the user doesn't choose the same item twice?  If you've got InfoPath 2007 you can use the new Multi Select List Box, but if you've got InfoPath 2003, you're still in luck, this blog entry is for you!
     
    Note: You should be familiar with XPath expressions before preceding.
     
    Let's start with a repeating table with a dropdown control bound to a secondary data source.
     
     
    There are a few choices when it comes to enforcing unique values selected by the user:
    1. Only show values that have not already been selected by the user.
    2. Show a validation error when the user selects something which has already been selected.
    3. Write code using the Changing event.
     
    This blog entry will cover both options 1 and 2.
     
    Option 1 - Only show values that have not already been selected by the user
     
    Only showing certain values implies that a filter is being applied to the dropdown.  To apply a filter, click the Filter Data… button when selecting the entries for the dropdown to show the condition builder.  Unfortunately, there is no UI in the condition builder to build an expression that means "don't show anything that is already in the list".  Thus, we'll have to construct this manually by selecting The Expression.
     
     
    You might be tempted to put the following expression:
    . != xdXDocument:get-DOM()/my:myFields/my:items/my:item/my:product
    This will return true if any one value from the list matches the current value.  In other words, this condition will always return true if there are two entries in the list which are different.  (Definitely not what we are looking for)
     
    The correct condition is a slight adjustment to the former expression:
    not(. = xdXDocument:get-DOM()/my:myFields/my:items/my:item/my:product)
    This will only return true if none of the values from the list matches the current value.  In other words, only values that are not in the list will be displayed.
     
    Preview the form and you will see that the dropdown only lists the products that have not already been selected.
     
     
     
    Option 2 - Show a validation error when the user selects something which has already been selected
     
    The only way this will work properly is if we add a hidden calculated field along with the product selection.
    (The reason for this is a bit too complex to explain here, so it'll have to wait for another time.)
     
     
    The formula for the unique field is the following:
    not(../my:product = (../preceding-sibling::my:item | ../following-sibling::my:item)/my:product)
    This will set Unique to true if and only if the product isn't already selected preceding or following the current item.
     
    The next and final step is to use data validation on the dropdown to show an error.
     
     
    Preview the form and you will see that the dropdown will show a validation error if the items are not unique.
     
     
    - Gary
    Software Development Engineer
  • Microsoft InfoPath 2010

    Andrew May knows XML Forms on SharePoint

    • 1 Comments
    This is a shout out to Andrew May, who's posted some great content on SharePoint as it relates to InfoPath and XML more generally.
     
    His most recent post covers the new Form content type that InfoPath uses for its Content Types integration. He's also got a great 5-part series on how the SharePoint XML parser works that InfoPath uses for our property promotion feature. He's even created a poster about how SharePoint parsers work, which you can download, print out, and hang in your bedroom, er, office.
     
    Another post covers the InfoPath integration with Document Information Panels and Workflows, which shows how important InfoPath dev skills are to the entire Office stack.
     
    On a completely unrelated note, the recent heat wave seems to have made it to Redmond, where we're in the 90's today. Yowsers!
     
    - Ned
    Program Manager
  • Microsoft InfoPath 2010

    New Article about the New Developer Features

    • 1 Comments
    Hi all,
     
    I wanted to let you know about a new MSDN article that has just recently been published which outlines the new developer features of InfoPath 2007. Feel free to post any questions or comments you have about the article.
     
    Thanks,
    Scott
  • Microsoft InfoPath 2010

    Multi-Select List Box: Requiring at least one entry

    • 2 Comments
    Yesterday I introduced the Multi-Select List Box and talked about how its data source is somewhat special: it binds to a repeating list of fields instead of a single field like the normal List Box does.
     
    When you need to ensure that at least one item is selected in the multi-select list box, you may be tempted to go to Muti-Select Listbox Properties to check the "cannot be blank" property; however, this property will not be available for multi-select list boxes because of their binding. Since a multi-select list box binds to a repeating field, what you really need is something that means "occurs at least once". Here's how…
     
    Visuals - Showing the red asterisk (*)
    1. Insert a multi-select list box and remove its border.
    2. Create a two-column layout table; place the multi-select list box into the first column of that table.
    3. Place an expression box into the second column of the layout table. Use static text * (asterisk) as the contents of the expression box and set its font color to red.
    4. Set up conditional formatting on the expression box:
          if count of elements in the repeating field is greater than 1, hide this control
    5. Set up a visible outside border on the layout table.
     
    The steps provided above will provide a visual indication to the user that the field is required - a red asterisk will be shown whenever the multi-select list box doesn't have any option checked. After you're done, you should see results similar to the following:
     
    Form Design
    Form Filling
     
    Preventing submit
    We still need to make sure that our users can't submit a form with this error - since nothing we've done above prevents form submission. This can be achieved in several ways:
     
    • Option 1: Use rules for form submission
    As the first step of submission, check if count of elements in the repeating field is less than 1. In that case, show an error message and stop processing all rules, essentially preventing form submission.
    • Option 2: Add data validation to another field
    if count of elements in the repeating field is less than 1. This will cause InfoPath to add an error to its Errors Collection behind the scenes if the condition is not met, and your users will not be able to submit the form.
    • Option 3: Write code for the Submit action
    In code you can check the condition and add elements to the Errors Collection as necessary.
     
    - Alex Weinstein
    Program Manager
  • Microsoft InfoPath 2010

    Introducing the Multi-Select List Box

    • 8 Comments
    InfoPath 2007 introduces a new control, the multi-select list box, for cases when you want to allow users to select one or more items from the list of options. This list of options may be static, or may come from a data source. For example, you may use a multi-select list box to let the user pick the cities affected by the marketing campaign:
     
    You may also allow users to specify items not on the list by going to Multi-Select List Box Properties, and setting the option to allow users to enter custom values:
     
    Data source
    Multi-select list box stores data in a repeating field. Every time a user checks an option, a new instance of the repeating field is added; every time an option is unchecked, a field is deleted. This is just like the Bulleted List control.
     
    Let's analyze the data source at design time, and what goes into the XML when the form is filled out:
     
    Form Design
    Form Filling
    Data Source Pane
    User Input
    Persisted XML
    <my:campaign>
         <my:city>Chicago</my:city>
         <my:city>New York</my:city>
         <my:city>Boston</my:city>
    </my:campaign>
      
    Default Values
    To specify which (if any) items should be checked in the multi-select list box by default, click Default Values on the Tools menu. Using the marketing campaign example, if you don't want any option to be selected by default, uncheck the only "city" item:
     
     
    When you do this, you may see a design-time message that the "Control is bound to a missing field or group". You can safely ignore this message in this case since the point is to not have any checked by default.
     
    If, instead, you want several options to be checked by default, right-click on the city item, then click "Add another city below", and specify default values for both cities:
     
     
    Compatibility
    Multi-select list boxes are supported only in InfoPath 2007 client.
     
    - Alex Weinstein
    Program Manager
  • Microsoft InfoPath 2010

    Don't settle for just one: Adding multiple default rows

    • 10 Comments
    Since I realize not everyone has installed the Beta yet (you can do it!), I figure it's time for a trick everyone can play with, even those still using InfoPath 2003.
     
    Starting with more than one row in a repeating table
    You may want to do this if you have a form where you know everyone's going to fill out at least five rows, or maybe some people will even print our your form before typing in their answers (I never!). You might even want to have five rows exactly, and then disable adding or deleting rows (in Repeating Table properties), but still use a repeating table to get the data structure you want.
     
    Regardless of your scenario, here's how to do it:
    1. Open the form in design mode
    2. Click Default Values on the Tools menu
    3. In the data source, select the group that's bound to the row of the repeating table
    4. Click the down arrow next to the group name
    5. Select "Add another row below"
     
     
    You can even specify different values for the columns of each row using the bottom of that dialog. And of course this works for any repeating item in your data source, not just those bound to repeating tables.
     
    Keyboard trick!
    Save yourself a few clicks by typing the "Insert" key instead of using the menu. Each time you type "insert" it will add another row. Those two clicks per row can really add up when you have a lot of rows! If you type it a few too many times, you can also use the "Delete" key to remove the offending rows. 
     
    Got your own tricks to share?
    As usual, if you've got your own tips in this area, or a cool reason to use this trick, please leave us a comment for the team to see and the community to gain.
     
    Enjoy,
    ned
  • Microsoft InfoPath 2010

    Got suggestions?

    • 8 Comments
    One of the reasons we started this team blog was to get your comments (spurred by our tips and tricks), so it's exciting to see more folks chime in. Let me just take a moment to fan the flames…
     
    We're listening
    We're always open to feature requests to help us plan for future versions. And we're also interesting in blog post suggestions, which we'll try to post on quickly. If you have kudos, well of course they're always welcome. So leave a comment to let us know what you're thinking!
     
    Need support?
    If you need help solving a specific question, you're better off in the newsgroups, where both the product team and InfoPath MVPs are on watch and where there's a large archive of other like-minded questions. For more general issues or something you suspect is a bug, check out the support center. And for common tasks and basic overviews Office Online is your best bet.
     
    Thanks!
    - Ned
  • Microsoft InfoPath 2010

    More than one way to write code: Visual Studio and InfoPath

    • 3 Comments
    If you need to write some Visual Basic or C# code behind your form, or maybe just some script, there are a few different tools you can use depending on which versions of InfoPath and Visual Studio you have.
     
    Here's a quick table summarizing it all:
     
     
    Note that both Microsoft Script Editor (MSE) and Visual Studio Tools for Applications (VSTA) come with InfoPath 2007 Beta, so you can open them from the Tools | Programming menu. If you don't see the one you want, change the language in Tools | Form Options. If it gives you an error that it's not installed, here's how to install them:
     
    1. If you are going to install VSTA, make sure you have the pre-requisites first:
    2. Go to Start > Control Panel > Add or Remove Programs
    3. Select your Office installation and click Change
    4. In the Office Setup wizard select to add features
    5. Find Microsoft Script Editor (under Office Tools) and/or Visual Studio Tools for Applications (under InfoPath > .NET Programmability) and select Run from my computer
    6. Finish the wizard
     
    Happy code writing!
    - Ned
  • Microsoft InfoPath 2010

    Advanced server-side authentication for data connections, part 3

    • 7 Comments
    This is the final segment of my three part series. In the first part of this series I introduced the concepts involved in three tier authentication. Then I covered single sign-on with some code. Now we'll go one step further…
     
    Authorization using the Web service proxy
     
    InfoPath Forms Services includes a Web service proxy which can forward SOAP requests to a Web service to enable authorization for a data query.  The premise is simple – the proxy runs under an account that is trusted by the Web service.   The Web service authenticates the trusted account.  In addition, the proxy sends the identity of the calling user in the SOAP header using a WS-Security UsernameToken.  The Web service can then use the provided identity to determine what data to return from the query.
    Setting up a connection to use the proxy is straightforward.  First of all, the connection has to use settings from a UDC file on the server.   The UseFormsServiceProxy attribute on the ServiceUrl element in the UDC file determines whether InfoPath and Forms Services will forward the Web service request using the proxy:
     
    <udc:ServiceUrl UseFormsServiceProxy="true">
      http://myserver/proxydemo/service.asmx
    </udc:ServiceUrl>
     
    Everything else on this end is automatic.  It's a little more interesting on the Web service end.

    It's tempting to consider using the WSE 2.0 library to consume the UsernameToken from the Web service request.  WSE 2.0 has methods to automatically consume WS-Security headers.  However, the default behavior of WSE 2.0 is to attempt to logon using the credentials in the UsernameToken.  It is possible to override the default behavior by specifying an alternate UsernameTokenHandler.  However, there is a more straightforward approach.
    First, declare an array of SoapUnknownHeader at class scope in your service:
     
    public SoapUnknownHeader[] unknownHeaders;
     
    Then declare a SoapHeader attribute for the web method:
     
    [WebMethod]
    [SoapHeader("unknownHeaders")]
    public ExpenseInfo[] GetMyExpenses()
     
    In your web method, look for the UserName element in the header array, which is returned as an XML Document.
     
    if (null != unknownHeaders && unknownHeaders.Length > 0)
    {
         // look for a userNameToken and return the username if present
         try
         {
              strUserName = unknownHeaders[0].Element.CreateNavigator().SelectSingleNode("//*[local-name(.)='Username']").Value;
         }
         catch (Exception)
         {
         }
    }
     
    In the example, I'm searching for a Username element anywhere in the headers.  To be more precise, the UserName is within a UsernameToken element, which is in turn under a Security header in the WS-Security namespace.  The entire SOAP header sent by the proxy looks like this:
     
    <SOAP-ENV:Header.xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
      <wsse:Security.xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis/security-secext-1.0.xsd">
        <wsse:UsernameToken>
          <wsse:Username>DOMAIN\username</wsse:Username>
        </wsse:UsernameToken>
      </wsse:Security>
    </SOAP-ENV:Header>
     
    I've put the code to get the username within a utility function called GetUserName.  In the function, I look first for the usernametoken.  If this is not present, I get the current Windows user.  In either case, I strip off the domain portion of the identifier and return the unadorned username.
     
    private string GetUserName(SoapUnknownHeader[] unknownHeaders)
    {
      bool fUserFound = false;
      string strUserName = string.Empty;
      if (null != unknownHeaders && unknownHeaders.Length > 0)
      {
      // look for a userNameToken and return the username if present
        try
        {
          strUserName = unknownHeaders[0].Element.CreateNavigator().SelectSingleNode("//*[local-name(.)='Username']").Value;
        }
        catch (Exception)
        {
        }
        if (string.Empty != strUserName)
        {
          fUserFound = true;
        }
      }
      if (!fUserFound)
      {
        // return the current Windows identity
        strUserName = WindowsIdentity.GetCurrent().Name;
      }
      // trim off the domain string if present
      int nDomainStringIndex = strUserName.IndexOf('\\');
      if (nDomainStringIndex > 0)
      {
        strUserName = strUserName.Substring(nDomainStringIndex + 1);
      }
      return strUserName;
    }
     
    In order to use the identity to retrieve data, I use it as part of the query against my database.  Here's the entire Webmethod. The code assumes that you have an Expense database with a table called Expenses, and that one column of the table, called Employee, contains the Windows username of the employee who filed the expense.
     
    [WebMethod]
    [SoapHeader("unknownHeaders")]
    public ExpenseInfo[] GetMyExpenses()
    {
      ExpenseInfo[] oReturn = null;
      DataSet oDS = new DataSet();
      string strQuery = string.Format("SELECT ExpenseID, Description, Date, Amount FROM Expenses WHERE Employee = '{0}'", GetUserName(unknownHeaders));
      try
      {
        m_Connection.Open();
        m_Adapter = new SqlDataAdapter(strQuery, m_Connection);
        m_Adapter.Fill(oDS, "Expenses");
        int cRows = oDS.Tables["Expenses"].Rows.Count;
        oReturn = new ExpenseInfo[cRows];
        for (int nRowIterator = 0; nRowIterator < cRows; nRowIterator++)
        {
          oRow = oDS.Tables["Expenses"].Rows[nRowIterator];
          oReturn[nRowIterator] = new ExpenseInfo();
          oReturn[nRowIterator].Amount = oRow["Amount"].ToString();
          oReturn[nRowIterator].ExpenseID = oRow["ExpenseID"].ToString();
          oReturn[nRowIterator].Date = oRow["Date"].ToString();
          oReturn[nRowIterator].Description = oRow["Description"].ToString();
        }
      }
      catch (Exception ex)
      {
      }
      if (m_Connection.State != ConnectionState.Closed)
      {
        m_Connection.Close();
      }
      return oReturn;
    }
     
    - Nick
    Program Manager
     
  • Microsoft InfoPath 2010

    Publish faster to even more places with InfoPath 2007

    • 6 Comments
    When designing a form template, publish is an important step to make the form available for end users of the form. In InfoPath 2007, we have made some modifications and improvements to the publish process. This article is intended to highlight some of the key changes you will encounter in the publishing wizard.
     
    Let us start off with a snapshot of the page in the wizard which helps you decide where to publish.
     
    Here is the second page in the wizard when you invoke File/Publish in InfoPath 2003.
     
     
    Here is the first page in the wizard when you invoke File/Publish in InfoPath 2007.
     
     
    Here are some key differences that you can notice:
    • Windows SharePoint Services server is now the default option and it can be used to publish to SharePoint server with or without InfoPath Forms Services. This option itself has several new features worth a blog post of its own.
    • Shared folder and web server options have been collapsed into one, namely, network location. This option includes the functionality of both shared folder and web server.
    • Email has been added to allow sharing templates via email. This functionality used to be available previously under File menu as "Send form as attachment". This option can be used to generate InfoPath email forms integrated with Outlook 2007.
    • Installable form template option has been added. This makes it really easy to create installable solutions which you may need to do if you are form's security setting is fully trusted.
    • A new branch to publish a Document Information Panel template on a SharePoint site has been added. However this option will show up only when it is relevant (i.e. you are customizing a content type in SharePoint).
     
    Work on it here, publish it there
    Another important difference is the concept of "working/developer copy" vs. "published copy". In InfoPath 2003, when you complete the publish wizard, your working solution will be the same as the published copy. In other words, any changes you are making from then on is on the published copy which may not be something you want to do. In InfoPath 2007, when you complete the publish wizard, your working solution is still the original copy that you were working with and subsequent changes to the solution will not affect the published copy unless you chose to publish those additional changes.
     
    Publish once, publish again
    We have also made it really easy to make updates to your published copy. Once you have successfully published once, the next time you go through the wizard, it will remember your previous information and automatically populate them for you. This makes it really easy to go through the wizard for subsequent publishing without having to re-enter various information.
     
    Hope you have a great experience publishing form templates using InfoPath 2007.
     
    Anand
    Senior Development Lead
  • Microsoft InfoPath 2010

    Introducing Horizontal Repeating Tables

    • 6 Comments
    InfoPath 2007 adds horizontal repeating table to the control toolbox for when you want data to be entered or displayed in a structured, tabular format, and when you want users to be able to add additional columns instead of rows.
     
    For example, you might use a horizontal repeating table to collect sales data for each quarter:
     
    Making it wrap
    When designing your form template, horizontal repeating table looks like a composite control -- it’s made from a horizontal repeating section and layout tables (I'll cover horizontal repeating section in my next post). Horizontal repeating table can be configured to wrap or scroll. By default, it will wrap to the next line, to provide a better printing experience.
     
    You can change the behavior of the control by resizing the layout tables; for example, to change the wrapping point, resize the rightmost border of the layout table:
     
     
    This will allow only two instances of the repeating column to fit on one line; the next two will go to the next line, and so forth:
     
     
    Making it scroll
    You may want to set an upper bound on the amount of real estate that a horizontal repeating table can take up; in that case, you need to make the control scroll. User experience will then be similar to the following:
     
     
    To achieve such behavior, you need to make the following modifications to your form template:
    1. Encapsulate the repeating section component of the horizontal repeating table in a scrolling region.
    2. Set the properties on the scrolling region:
      • Show horizontal scroll bars: always
      • Show vertical scroll bars: never
      • Wrap text: unset
      • Margins: all zero
      • Padding: all zero
      • Size: appropriate height and width
      • Borders: no borders
    3. Resize the rightmost border of the layout table that contains the horizontal repeating table to match the border of the scrolling region.
     
    When you’re done, your form template will look similar to the following in Design mode:
     
     
    Scrolling is often desirable for electronic forms, but is not ideal for printing. If you want to achieve both, you need to use scrolling in the view that users will see when filling out the form and wrapping in an associated printable view.
     
    Data binding of a horizontal repeating table is identical to that of a regular repeating table or section.  Horizontal repeating tables support conditional formatting, data validation, rules, calculations, other InfoPath data features that a regular repeating tables support.
     
    Note that horizontal repeating tables are only supported in InfoPath 2007 client.
     
    - Alex Weinstein
    Program Manager
  • Microsoft InfoPath 2010

    Advanced server-side authentication for data connections, part 2

    • 4 Comments

    In the first part of this series I introduced the concepts involved in three tier authentication. Now let's drill into the details and work with some code.

     

    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.Write("<P><A href=\"" + CredentialsManagementUrl.ToString() + "\">Click here to enter your credentials</A></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.Write("<P><A href=\"" + CredentialsManagementUrl.ToString() + "\">Click here to enter your credentials</A></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
  • Microsoft InfoPath 2010

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

    • 4 Comments
    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
  • Microsoft InfoPath 2010

    Open your rolodex from InfoPath using the Contact Selector

    • 8 Comments
    Speaking of Outlook integration, Microsoft Office 2007 includes a new control that enables you to choose one or more e-mail address from the address book.
     
    You can add this control to InfoPath’s list of custom controls by using the Add or Remove Custom Controls wizard like you would for any other ActiveX control.  When registering the control, you can choose most of the default options. However, you must choose "Field or Group (any data type)" in the "Specify Data Type Options" page of the wizard. If you don't choose this binding type, the control will be disabled when you try to fill out the form.
     
    When you insert this control in a form template, it looks like this:
     
     
    When you insert this control in design mode, only a group node is added to the data source. You must manually add additional fields in order for this control to work correctly. To determine the final data structure should be, open the properties dialog for the control and click on the "Items" tab. This tab lists the schema structure that is required.
     
    As I mentioned, you must manually add these fields to the data source. This can be quite painful if you want to use the control in a lot of form templates. However, here’s a little trick.  You can create a Template Part that contains only the data structure and no controls in the view. Now, when you need to use the Contact Selector, first insert the Template Part to create the data structure.  (This will insert an empty Section control into the view which you can then remove.)  Then, go to the data source, right-click on the group node that was inserted, and select Contact Selector from the More menu.
     
    Template Parts don't support ActiveX controls so you can't insert the Contact Selector into the template part which would make this even easier. However, using this empty template part that contains only the data structure is still easier than creating the structure from scratch each time.
     
    Scott Roberts
    Senior Development Lead
  • Microsoft InfoPath 2010

    Accessing InfoPath forms from Outlook

    • 16 Comments
    We have made significant investment in Office 2007 to better integrate InfoPath with Outlook. To that effect we have made it really ease to use InfoPath forms from within Outlook. When you email InfoPath forms from InfoPath 2007(using File/Send To Mail Recipient or Email submit adapter), you will now have an enriched experience when viewing these InfoPath e-mail forms. In this post, I highlight just one of the several features that we have added to Outlook 2007.
     
    Let us say, while you are working on your emails, you remember that you need to fill out a (InfoPath) form. You don't need to switch from Outlook any more. You can access the InfoPath dashboard from within Outlook by clicking on the "Choose InfoPath Form" option under "New" menu as shown below.
     
     
    This will bring up a condensed version of the regular InfoPath "Fill out a form" dialog. Most of the editor functionality is available in this condensed version. If you need to switch to InfoPath design mode (or use any additional functionality not exposed in this condensed version) then you can click on "Open InfoPath" button at the bottom left of this dashboard to launch InfoPath application:
     
     
    To learn more about InfoPath Outlook Integration I encourage you to visit Tudor's blog titled "Using InfoPath e-mail forms" at http://blogs.msdn.com/tudort/archive/2006/02/22/536800.aspx 
     
    Hope you found this article useful and are interested in exploring the numerous features that Tudor talks about in his blog.
     
    Thanks!
    Anand
    Lead Software Design Engineer
  • Microsoft InfoPath 2010

    Advanced server-side authentication for data connections, part 1

    • 8 Comments
    To tier three... and beyond!
     
    Real-world enterprise applications are seldom restricted to a single server.  Anyone who has created a nontrivial multi-tier application in a Windows environment has had to work around a fundamental limitation in NTLM authentication:  namely, that NTLM authentication tokens cannot be delegated past the second tier.
     
    Could you bounce off the wall and say that again?
     
    OK, in simpler terms:
    When you log onto your workstation, you present windows with primary evidence of your identity in the form of a username and a secret – usually a password, but sometimes a certificate or a biometric identifier such as a fingerprint.
     
    When you connect to a web application in a browser, your workstation contacts the web server and tells the server who you are.  The server trusts the workstation because it knows that the workstation has primary evidence of your identity, but the server has only second-hand evidence.
     
    When the web server connects to the data server, it passes your authentication token, but the data server won't accept it because the chain of trust is too long.  The data server has only third-hand evidence of your identity.  Bzzzzzzzzzt – thank you for playing!
     
    With InfoPath 2003, you never had to worry about these issues when designing your form.  You ran InfoPath on tier 1, and the database, Web service, or SharePoint site on tier 2 trusted your computer's first-hand evidence.  Now that you are designing forms that run in a web browser, you'll need to think about tier 3.
     
    There are a number of ways of dealing with tier 3 and beyond in forms services.  I'll start by briefly describing three simple techniques for noncritical applications, then I'll move on to enterprise-quality solutions, culminating in two technologies that are specific to Microsoft Office SharePoint Server.
     
    Keep in mind that for form templates that are not admin-approved and fully trusted, the connection settings need to be stored in a Universal Data Connection (UDC) file in a Data Connection Library in order to make a connection to another domain.
     
    Anonymous connections
    For trivial data connections, such as looking up a list of states to populate a drop-down list, you can simply allow anonymous users to access your data.  Removing the need to authorize the user means that it's no longer a problem that your identity can't be verified on tier 3.
     
    HTTP Basic Authentication
    In Basic authentication (or digest, which is a slightly more secure version of the same protocol), your browser prompts you to enter your username and a password, which are then passed in cleartext (or in digest form) to the web server.  The web server now has primary evidence of your identity, so the data server can trust it to tell it who you are.  You can set up IIS on your SharePoint server to use Basic authentication instead of Windows Integrated authentication.  While this is a quick way to do an end run around the tier 3 problem, it presents an awkward user experience on the intranet.   This is better suited to the extranet, where getting prompted for additional credentials is a more familiar experience. Don't forget to set up SSL so that your users' credentials are encrypted on the wire.  Otherwise, anybody monitoring your server traffic can read the passwords as they pass by.
     
    Embedded SQL credentials
    It's common practice in web applications to connect to a database using a SQL username and password embedded in the connection string.  Since this requires putting a password in cleartext in a configuration file, it is not considered a secure method of authentication.  By default, user form templates on the server are not allowed to use embedded SQL credentials.
     
    Kerberos
    Unlike NTLM authentication, a Kerberos authentication token, called a "ticket", can be independently verified at any point in an n-tier system and thus can be delegated indefinitely within the window of time that the ticket is valid.  For enterprises where Windows XP or better is the standard desktop and Windows Server 2003 is the standard server, Kerberos can replace NTLM as the standard authentication method in Active Directory.  This is the preferred method of overcoming the 2-tier restriction on token delegation when available.
     
    Constrained Delegation
    In constrained delegation, two services on two servers can be configured to allow a specific set of user accounts to be delegated from one service to the other without requiring independent verification of a password.  While this is considered a secure option, it is notoriously difficult to set up and maintain.
     
    Office Single Sign-on
    Office Single Sign-on (SSO) is a service on Microsoft Office SharePoint Server which was created to help applications on the server overcome authentication delegation issues.  At its heart, SSO is simply a database which stores encrypted username and password pairs.  An application running on the server can obtain a username and password associated with a known SSO application definition and can then use those credentials to log on to Windows and make a trusted connection to a data source. A form running on the server can use SSO to connect to external data by specifying an SSO application ID in the UDC file containing the connection settings.
     
    Web service proxy
    InfoPath Forms Services includes functionality to forward Web service requests from a form.  The web service request is made using the identity associated with the SharePoint web application.  In order to allow the web service to authorize access to the external data, the user's Windows username is passed in the SOAP header using a WS-
     
    Security UsernameToken
    In my next two installments, I'll describe in more detail how to use Office Single Sign-on and the Web service proxy to connect to enterprise data from your browser-enabled forms.
     
    In my next post we'll cover Single Sign On and write some code.
     
    - Nick
    Program Manager
  • Microsoft InfoPath 2010

    Improvements to Share Point integration - Property demotion

    • 10 Comments
    One of the new features in InfoPath 2007 when publishing to a SharePoint 2007 server is the ability to turn on property demotion.
     
    Property demotion is the ability to be able to modify fields that show up in SharePoint document libraries and cause those fields to be automatically updated in the underlying document (in this case InfoPath form).
     
    Where would you use demotion?
    Imagine you have a document library where you save your company assets as InfoPath forms. Let us say one of the fields in the library, is the current owner of this asset. When you need to bulk assign a bunch of assets from one person to another, wouldn't it be really easy if you can just update this field in a data grid view instead of opening each and every asset form and having to update it.
     
    Let us see how you can enable property demotion
    When you go through the publish wizard (File/Publish) pages for publishing to SharePoint, InfoPath will detect if the server is 2007 and if it finds that to be true, you will now be able to turn on property demotion for a field by selecting the check box as shown in the image below.
     
     
    Note that not all data types can be demoted and also fields that are within a repeating context cannot be demoted. For data types that don't allow demotion, the checkbox will automatically be disabled.
     
     
    Once you enable certain fields for demotion, they become available in SharePoint's data grid view to be edited. The data grid view can be accessed from SharePoint library using the Actions menu as shown below.
     
     
     
    Also since demotion happens on SharePoint side (when the field is edited), the form's business logic such as Data Validation, Rules, Formulas, Code and Script will not run at that time. So there may be situations when you do not want to turn on demotion for certain fields.
     
    Hope you find this helpful and look forward to see you turning on demotion.
     
    Thanks,
    Anand
    Lead Software Development Engineer
Page 7 of 12 (298 items) «56789»