Monday, July 5, 2010

Downloads for Presentation on WSPBuilder July 13, 2010

There are two files available for download on the Presentation on WSPBuilder. The first is an html file which contains links for WSPBuilder articles. The second is a demo project for event handlers with a feature receiver.

Saturday, May 1, 2010

Download load for SharePoint Saturday Talk “InfoPain and Beyond”


The two files are available for download from the SharePoint Saturday Talk "InfoPain and Beyond". The first is the power point slides, InfoPain and Beyond PowerPoint; the second file include the demo examples and text of the managed code, TravelRequestDemo. The second file is zipped so it will need to be unzipped first.
Next, one at a time open each of the three xsns with managed code (TravelRequestv02.xsn. TravelRequestv03.xsn and TravelRequestv04.xsn) and change the path to the managed code and resave the file; as it will be in a different location on your machine when it's unzipped. In InfoPath the location for the managed code is located the Tools Menu=>Form Options Programming.

Saturday, April 10, 2010

Mapping InfoPath Promoted Columns to Site Columns


Site Column Tribble Phenomenon in InfoPath 2007

Property promotion and column mapping in InfoPath 2007 is anything but straight forward. Column mappings can be arbitrarily changed when new InfoPath fields are inserted or deleted. This can even happen when a field name or data type is changed within a previously published form. For example, a form field named 'EventDate' might be initially mapped to the internal name 'EventDate' in a form library. This column might be subsequently be remapped by InfoPath to 'EventDate1' on re-publication. This wreaks havoc when a workflow or event receiver attached to the form is expecting specific column names. A workflow might blow up with a mysterious error or enter a section of code not dictated by your understanding of the logic. As a programmer, you might spend hours trying to debug the workflow only to find the property names on the exported variables have changed and the problem is with the form.
[Ouch-been there! Of course, it only happens on a highly visible production systems.]

Several authors have posted good descriptions of this phenomenon:

Tedious Workaround

The good news is that this phenomenon is entirely controllable; the bad news is that it's tedious to fix. This article demonstrates a procedure that when completed will allow a re-published form to preserve the field mappings established unless specifically altered in the Property Promotion step of form publication.

First, a WSPBuilder project will be created as a SharePoint Feature; next, the feature will be deployed and activated to a site collection. Then, the form fields will be explicitly mapped to the newly created site columns. Finally, the form will be published to a SharePoint Form Library.

The form being used is a simple InfoPath Form I call "Significant Accomplishments". Despite the name, there is nothing significant about this form. It is simply an InfoPath form used to collect a few pieces of data about accomplishments that impact a given organization. The form is being designed in conjunction with a workflow that sends email notifications. The workflow is not a "happy camper" if the names of its Item properties change.


The new site columns will be built around the promoted columns in the InfoPath form:



Note:  This blog assumes you can create an InfoPath Form with following fields list in the above "Form Options". How the form looks is your call. The focus of the blog is on WSPBuilder Feature Creation and field mapping.

Creating the Visual Studio 2008 WSPBuilder Project

[Two great articles on WSPBuilder are WSPBuilder - Walkthrough of the Visual Studio Add-in by Tobias Zimmergren and Intro to WSPBuilder by Michael Bowers.]

Starting off with Visual Studio 2008 :



Next we choose to create a new WSPBuilder project in C#:  I have chosen "Significant Accomplishment Fields" for the Project Name.
[This is also the name chosen for the blank feature to be added shortly.]



Next in the Solution Explorer I add two folders (TEMPLATE and FEATURES) to simulate the directory structure of the 12-hive in SharePoint. (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12) under the 12 directory (12\TEMPLATE\FEATURES):

Match the singular and plural in the folder names exactly to match the 12 hive or you may end up creating undesired directories in the 12 hive and have difficulty finding and utilizing your feature (Experience).  Also for consistency capitalize the directory names as in the example.

Your structure should be identical to the following:

 Next choose "Add" a "New Item" to the project.


The new item will be a "Blank Feature" under the "WSPBuiler" category:  As stated earlier, I used the same name for the feature that I did the Project: SignificantAccomplishmentFields.



Next the project template will pop-up a Feature Settings dialogue: Enter some Description. From the Scope drop down, choose "Site" to make the feature a Site Collection feature.



Your Solution Explorer in Visual Studio 2008 should look as follows:



The two main files for this feature are feature.xml and elements.xml. The feature.xml should be pretty static with no editing necessary:


The only difference between your files and mine will likely be the Id field. The elements.xml file is where you will define the fields manually. Mine look as follows:




A couple of quick notes:
  1. Each ID is unique—you will generate different guids than mine.
    [More below on generating unique guids.]
  2. To make the fields "kind of unique" within the Site Collection, I chose to preface each field with something meaningful to my project "SigAcc". In the form library Form Settings page you will actually view the "DisplayName".  Also that is the field the workflow or event receiver will use[More about guid uniqueness at the conclusion of the blog.]
  3. For the Group field choose a meaningful name for grouping your columns, I chose "Significant Accomplishment Site Columns".  The site columns will be displayed under this group on the Site Columns page under Site Settings.
To obtain individual guids for the ID columns use the Visual Studio "Create Guid" Tool located under the "Tools" menu in Visual Studio 2008.



The "New GUID" button generates new guids and the "Copy" button will insert them into the paste buffer. Choose option "4. Registry Format". The braces around the guid should be part of the insert.

Note: All Fields must have a unique ID or it will cause you problems later. This is tedious but necessary.

After entering in all your fields, all that left it to build the wsp solution and deploy. If you are building on the your deployment machine just right-click on the project name and choose "Build WSP".



Next right-click again and choose the option below to deploy.

If you are deploying this feature to another machine, the following statements can be placed into a batch file, e.g., "xyz.bat" and executed along with the wsp solution file:

prompt $D $T$_$P$G
@echo Please set the correct path to wsp and site collection before running this script OR hit Ctrl+C to exit
@pause
set pathwsp="c:\wsp\SignificantAccomplishmentFields.wsp"
set pathsitcollection="http://saovaio-pc"

cd "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\bin"

stsadm -o deactivatefeature -name SignificantAccomplishmentFields -url %pathsitcollection% -force
stsadm -o execadmsvcjobs

stsadm -o retractsolution -name SignificantAccomplishmentFields.wsp -immediate
stsadm -o execadmsvcjobs

stsadm -o deletesolution -name SignificantAccomplishmentFields.wsp -override
stsadm -o execadmsvcjobs

@pause

@echo Adding back WSP

stsadm -o addsolution -filename %pathwsp%
stsadm -o execadmsvcjobs

stsadm -o deploysolution -name SignificantAccomplishmentFields.wsp -allowgacdeployment -immediate -force
stsadm -o execadmsvcjobs

stsadm -o activatefeature -name SignificantAccomplishmentFields -url %pathsitcollection% -force
stsadm -o execadmsvcjobs

[Watch the line breaks on a few of these commands since they can't be displayed on one line in this blog.]

[NOTE: Be sure to change your pathwsp and pathsitecollection variables to your directory and site collection before running this script. Also note the script begins by getting rid of the old feature and solution. It will not hurt anything to leave this in and it may come in handy as you add new site columns and need to retract and delete the old feature.]

Should the deployment portent well; you will be able to see your site columns on the Site Column page . Be sure that all columns are present and accounted for—you may have inadvertently duplicated a guid or have a conflict with a reserved site column like "Title". Also you should see your feature activated in Site Collection Features.
[More about reserved columns at the end of the article.]




[When re-publishing site column features I religiously "Deactivate" and re "Activate" the features from this page to make sure my columns appear.]

Mapping the InfoPath Exported Fields to the Site Columns

After you create your InfoPath form, create a folder called "Source Files" or any other name you desire.
This folder will be used to store the extracted source files.  Mine was placed in the same directory as the form—but whereever you want to place yours is fine. This will simplify the next step in saving "Source Files". Next open your form in "Design Mode" and choose from the "Files" menu the option "Save as Source Files"; then, navigate to the directory just created and choose "OK".
[If you don't save to a folder, all files get dumped into your immediate directory—yuck!!]


The following shows the files that were created by my form:.
           

[There is nothing magic about extracting the source files. This can be done by simply changing the extension on the "xsn" file.  The InfoPath "xsn" file is really a "cab" file.  The "cab" file is similar to a "zip" file with a lot of files combined. Once you change the extension of "xsn" to "cab" and you can double-click the file and  extract them.  Be sure to change the extension back if you want the form to function in InfoPath.]

The only file will be changing is the "manifest.xsf".
Now close your InfoPath form. It will probably ask you to save—that's fine. If the InfoPath form is not closed, you will not be able save back changes to the manifest.xsf file because it will be locked in memory by InfoPath.

The steps for the next part are
1) Open the file with NotePad or a suitable text editor.
[I actually used Visual Studio but had to copy the manifest.xsf to NotePad first—then paste it into Visual Studio—then reverse the process to save the changes]

2)  For each of  your promoted properties you will locate the corresponding columnName guid in the listProperties section.  Then, search to locate that same guid in the listPropertiesExtension section. This listProperties section is located farther down in the file than the listPropertiesExtension section.  I mention this fact because your search direction will be "up" not "down" as one would normally search in a file.


       

3) Once you have located the corresponding guid in the listPropertiesExtension section, replace or insert the guid from your Site Column Features project into the columnId field for the promoted property that you want to map. If the form has not been published, the column id in the listPropertiesExtension section will most likely be blank (columnId=""). Continue this process until all columnIds of your promoted fields have been inserted or have replaced the existing guid.

[This is painfully tedious but needs to be followed carefully. In my particular case, there are six columns to map. Just remember a guid, guid here and a guid,guid there—here a guid—there a guid—everywhere a guid, guid :-)]
       
4) After all columns have been mapped, close the manifest.xsf, To recreate the InfoPath form with the new mappings, right-click the manifest.xsf and choose "Design". (Double-clicking will not work; InfoPath will try to open the form for inputting data.). At this point your form is no longer connected to your original form and you need to do a "Save As" to maintain this changed version. Of course, InfoPath will forget your current file location when you try to save. Try to think kind thoughts as you navigate to where you want to keep the file—which in my case, is the original directory with the other file. I save my files with a version number like v01, v02. With InfoPath I never know when I'm going to need to scramble for an older version.

5) Publish the form normally by creating a new form library. Remember to go into Advanced Setting to make sure the form can be displayed in a browser.

6) Should luck hold your site columns will be safely attached to your form library—snug for the onslaught of data entry and re-publishing.



Further Learning on Site Columns

With the above recipe you should be able to shore up your InfoPath Forms so that your internal variable names stay constant. As I stated in my introductory blog, I'm a learner as well. There are a few points I didn't expound on because the internal plumbing of SharePoint is not totally clear to me. Are Site Columns unique? It's not that simple.

When I originally created my Site Columns, I used the name "Title" for one of my fields—it never worked. It never showed up in my group. There are reserved or predefined columns in SharePoint that you can't use.
(If someone out there know where to find all of these--please enter a comment to this blog.)
However, if not using a reserved column the Name column doesn't have to be unique as long as the ID is.

Just for grins and giggles, play with this Element.xml in a new Site Column Feature (change the guids if desired):


Under Site Columns, it displays this way on my Windows 7 SharePoint Installation:

Also try to enter "Title" for a new Site Column through the Web Interface of Site Columns.

You will receive the following message:

It's interesting through the Site Columns web interface I can only enter the "AnthingElse" as a Site Column once; whereas in my feature I can do it multiple times.
[My reasons for entering the columns multiple times is just to understand underlying the technology.]

Please let me know if the headaches have gotten worse or better. I'm on tap for pain management.

I be blogging at y'all later.

Monday, March 29, 2010

Beam me up to InfoPath Blogosphere, Scottie!!

Why I be A'Bloggin especially about InfoPath.


 

All software has bugs. Software is oversold (I probably wouldn't be working if this weren't the case). It's always partially vaporware at its onset: more promise and potential than fulfillment. Software from prominent vendors like Microsoft evolves over time to fix most of the major discrepancies (but the process of living through these bugs is painful). InfoPath qualifies big-time for the above statements.

In my estimation, InfoPath is a 70-15-15 percent solution: 70 percent works as expected; with managed-code and sweat equity, another 15 percent is doable; the last 15 percent requires special trickery or would be better handled in another technology such as ASP.net Web Pages, SharePoint Web Parts or SharePoint Features. An excellent article that further illuminates this point is one by Jacques du Preez, The Joy, Blood, Sweat And Tears Of InfoPath 2007

My first technical post will demonstrate a method that I've successfully used to map InfoPath columns from my forms to site columns. These site columns are specifically defined in a feature using a WSPBuilder project. This technique eliminates a problem where InfoPath maps exported columns to random columns in the destination form library, changing their internal names willy-nilly. For example, a form column named 'EventDate' might be initially mapped to the internal name 'EventDate' in a form library. After republishing the same form on a moonlit night on the Ides of March, the column might be remapped to the internal name of 'EventDate1'. This wreaks havoc when a workflow or event receiver attached to the form is expecting specific internal column names. For another description of this problem check out "Problem 4" in Ryan Thomas's column Automatic Creation of InfoPath forms - not as easy as I thought.

My second technical post will cover using a SharePoint List as a data-entry table for drop-downs in InfoPath. Setting up a list is simple enough; however, getting the list sorted and filtered for the Infopath Form is beyond the capabilities of the InfoPath graphical Data Connections interface. To get this functionality, I had to resort to managed code which I gleaned from the master S.Y.M Wong-A-Ton Filter and sort a SharePoint list in InfoPath using a DataView.
(Sorting and filtering SharePoint Lists for InfoPath drop-downs will no longer be an issue in SharePoint 2010—but currently in SharePoint 2007 it is an issue. Even if this release was live today, going to the next release is not always an option in a complex production environment.)

Just so we're on the same page, when I use InfoPath it's generally in conjunction with a larger SharePoint programming project that could involve workflows, event receivers, other lists and possible databases. Often these projects can take months to develop. A specific example in my programming career that stood out involved an InfoPath form used to arrange meetings. This form was used in conjunction with a workflow to send meeting requests after being approved with a digital signature—piece of cake, right?

In our IT environment digital signatures took four months to implement and required five System Engineers, two Microsoft Support Analysts, one Group Policy Specialist and me, a lowly programmer. It turns out that Microsoft had developed this piece basically for power users that had the rights to download the digital signature ActiveX controls on to their own machines. Our environment precludes users from downloading and installing controls because of Group Policy restrictions. We had to repackage the ActiveX Controls so that they could be pushed out to our user community. Also our Group Policy Specialist had to play extensively with our Group Policy settings to make this happen.
(I actually attempted a digital signatures piece with a former employer. There was insufficient system engineering support in this environment and it never worked. My Takeaway is that you might not be dumb and it still might not work. The issue may be more complex than you suspect. Take Microsoft examples with a couple grains of salt or a small dead sea.)

On an InfoPath project, I need a wide range of inputs to develop a user-friendly form solution. I conduct numerous Google searches. Sometimes I come across the perfect solution but can only stare at it longingly because the author has either left me at step 3 or made an assumption beyond my experience. I hope this blog will be another resource for you. Seeing a problem from a different angle or just getting more examples can cause something to gel. It is not possible in InfoPath to have too many examples.
(Can a sore index finger from Googling qualify for Workman's Comp?)

One additional reason for my wanting to blog is that I'm a learner and writing helps me to explore more fully. Two of my hot topics are SharePoint Content Types and WSPBuilder , so you can expect to see blogs on each of these topics.

I invite your contributions.

Transport Out.