Help InfoPath forms and MOSS 2007 get along…
Have i talked you about real life stories J… well here is another one. This time is about MOSS 2007 and InfoPath forms and about getting a new column for a promoted field that was already assigned to a Site column (resulting in duplicated Site Columns). This happens when you already have a published form, you make some changes to it, and then you deactivate the previous form, upload the changed one and reactivate it.
Why does this happen?
I had a customer that was having this problem with one of his InfoPath forms and I could not figure out why. I did not know if the problem was on the MOSS side or the InfoPath side. It never happened on the first time the form was published, it always happened when something changed on the form and the form republished. So I started troubleshooting from the InfoPath side, by comparing the two versions of the InfoPath form to check what had changed (the customer stated that the changes to the form had only been a few cosmetic ones). In order to do that I saved the two versions of the InfoPath forms as Source Files.
This option allows to view all the files that constitute the form. The next step was to compare the two versions and see if the differences could give us a clue. There it was, something odd! In one of the versions some column ID´s were not set in the manifest.xsf file.
InfoPath Form V1 |
InfoPath Form V2 |
<xsf2:fieldExtension columnId="" readWrite="no" columnName="{BD102547-0969-4045-A365-8FC1FEE85C0A}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="68cfdd67-ac6b-4f91-979f-065c1fb4f668" readWrite="no" columnName="{BD102547-0969-4045-A365-8FC1FEE85C0A}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="" readWrite="no" columnName="{7D192010-DB9C-4E86-B4D8-D7F68B3C2FCC}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="5661440d-2f61-4383-a217-f7730fb9a3a6" readWrite="no" columnName="{7D192010-DB9C-4E86-B4D8-D7F68B3C2FCC}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="" readWrite="no" columnName="{35387C25-2634-41A8-A866-C26B1AD30827}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="{64cd368d-2f95-4bfc-a1f9-8d4324ecb007}" readWrite="no" columnName="{35387C25-2634-41A8-A866-C26B1AD30827}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="" readWrite="no" columnName="{D6C10D8E-0A84-4C01-B275-DCBCB45EF995}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="{8A121252-85A9-443d-8217-A1B57020FADF}" readWrite="no" columnName="{D6C10D8E-0A84-4C01-B275-DCBCB45EF995}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="" readWrite="no" columnName="{EF224E14-E324-47D4-9345-0BC24BF3E781}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="35919541-07d5-4008-b197-403f8a87ffb1" readWrite="no" columnName="{EF224E14-E324-47D4-9345-0BC24BF3E781}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="" readWrite="no" columnName="{185F33F0-C353-46C8-BC9A-11529D9D10C6}"></xsf2:fieldExtension> |
<xsf2:fieldExtension columnId="337fbab4-01e2-48dc-ae6e-353317fc78d9" readWrite="no" columnName="{185F33F0-C353-46C8-BC9A-11529D9D10C6}"></xsf2:fieldExtension> |
Each of these entries on the table above relates to an entry like the one below, in the same file and are related by the columnName property:
<xsf:field name="Activity Number" columnName="{BD102547-0969-4045-A365-8FC1FEE85C0A}" node="/my:myFields/my:ActivityNumber" type="xsd:string"></xsf:field>.
When you make changes to an InfoPath form and some of those changes affect the field definitions, sometimes the InfoPath designer modifies the definition of those fields, changing the GUID of the field, and in some cases even clearing the GUID of that field. This causes the publishing process to create new columns, as it origins the relations between form fields and MOSS fields to break.
The workaround
In theory if this column ID´s would match the ID’s in the MOSS Site column ID, the problem should be solved. To know the ID´s of the Site Columns I did a small PowerShell script to list the ID and the name of the columns of a certain content type.
Param([string]$url = “https://localhost:80”, [string]$contentType = “Item”) [System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint”) Try { $site = New-object Microsoft.SharePoint.SPSite($url) $web = $site.OpenWeb()
#To list guids $type = $web.ContentTypes[$contentType]
Write-Host ‘Selected Content Type: ‘ $contentType Write-Host Id’ ‘ Title Write-Host ------------------------------------ ‘ ‘ ----------------------------- foreach ($f in $type.Fields) { Write-Host $f.id ‘ ‘ $f.title } } Finally { if ($web –ne $null){ $web.Dispose() } if ($site –ne $null){ $site.Dispose() } } |
Table 1: ListCTypeFields.ps1
The output for calling the script, for example for the content type SampleContentType, would be something like:
> .\ ListCTypeFields.ps1 –url “https://localhost:6496” -contentType “SampleCType”
|
Using the script above what you have to do is to validate each field columnId in the manifest.xsf, filling the ones that do not have value like the example below, or correcting the GUID so the columns ID’s would match.
Using our sample file manifest.xsf and considering the fields:
<xsf:fields>
<xsf:fields>
<xsf:field name="Activity Number" columnName="{BD102547-0969-4045-A365-8FC1FEE85C0A}" node="/my:myFields/my:ActivityNumber" type="xsd:string"></xsf:field>
<xsf:field name="Audit Status" columnName="{7D192010-DB9C-4E86-B4D8-D7F68B3C2FCC}" node="/my:myFields/my:AuditStatus" type="xsd:string"></xsf:field>
<xsf:field name="Start Date" columnName="{35387C25-2634-41A8-A866-C26B1AD30827}" node="/my:myFields/my:StartDate" type="xsd:date"></xsf:field>
<xsf:field name="End Date" columnName="{D6C10D8E-0A84-4C01-B275-DCBCB45EF995}" node="/my:myFields/my:EndDate" type="xsd:date"></xsf:field>
<xsf:field name="Audit Title" columnName="{EF224E14-E324-47D4-9345-0BC24BF3E781}" node="/my:myFields/my:Title" type="xsd:string"></xsf:field>
<xsf:field name="Auditors" columnName="{185F33F0-C353-46C8-BC9A- 11529D9D10C6}" node="/my:myFields/my:csAuditors/my:Person/my:DisplayName" type="xsd:string" aggregation="merge"></xsf:field>
</xsf:fields>
…
Corrected manifest.xsf would be something like (remember that the fields definition relate to xsf2:fieldsExtension by the columnId):
<xsf2:listPropertiesExtension>
<xsf2:listPropertiesExtension>
<xsf2:fieldsExtension>
<xsf2:fieldsExtension>
<xsf2:fieldExtension columnId="c042a256-787d-4a6f-8a8a-cf6ab767f12d" readWrite="no"
columnName="{BD102547-0969-4045-A365-8FC1FEE85C0A}"></xsf2:fieldExtension>
<xsf2:fieldExtension columnId="5f47e085-2150-41dc-b661-442f3027f552" readWrite="no"
columnName="{7D192010-DB9C-4E86-B4D8-D7F68B3C2FCC}"></xsf2:fieldExtension>
<xsf2:fieldExtension columnId="8553196d-ec8d-4564-9861-3dbe931050c8" readWrite="no"
columnName="{35387C25-2634-41A8-A866-C26B1AD30827}"></xsf2:fieldExtension>
<xsf2:fieldExtension columnId="8c06beca-0777-48f7-91c7-6da68bc07b69" readWrite="no"
columnName="{D6C10D8E-0A84-4C01-B275-DCBCB45EF995}"></xsf2:fieldExtension>
<xsf2:fieldExtension columnId="fa564e0f-0c70-4ab9-b863-0177e6ddd247" readWrite="no"
columnName="{EF224E14-E324-47D4-9345-0BC24BF3E781}"></xsf2:fieldExtension>
<xsf2:fieldExtension columnId="28cf69c5-fa48-462a-b5cd-27b6f9d2bd5f" readWrite="no"
columnName="{185F33F0-C353-46C8-BC9A-11529D9D10C6}"></xsf2:fieldExtension>
</xsf2:fieldsExtension>
</xsf2:fieldsExtension>
</xsf2:listPropertiesExtension>
This way the duplicated fields problem is solved and the correct field will be associated to the correct Site Column. All that is left to do is to save the form as a .xsn file again and publish it.
See you next time…
Comments
- Anonymous
August 30, 2011
Hi Rui, excellent post! it really helped me. I'll try the powershell script later, but with the explanation was enought. But i've got one question left, is it possible to set the internal name of the sharepoint column from the manifest.xml? Tha will really help at the time of making a SPQuery and mapping the fields. I know i can make a SPQuery based on the GUID of the fields, but i already have a framework that does that with the internal names. Thanks, Guillermo