I embarked on our first major InfoPath based solution looking forward to sunny days. My biggest mistake seems to be not leaving my ASP.NET mindset behind.
I started out creating a form that looks up data based on an id from a service and updates the data. I wanted the form to load data for editing on open, freeing users from having to query with the id manually. The form was supposed to be deployed on several Sharepoint sites, each with a different id for looking up the data. I figured that InfoPath must have some way of beein parameterisized, but no, not without somehow altering the xml of the source document. What I really wanted was some kind of QueryString.
My first hunch was to promote the id field from the form to the form library and the alter the value in the form library, but it's read-only. Editing the properties.xfp file in the Form Library Forms directory removes the read-only, but the value does not propagate two ways, only from the form to the library.
My second hunch was to relink the form in the form library, but this only changes the processing instruction of the xml document, doing nothing with the data connections in the template. Same applies for the Processing Instruction Update Tool in the InfoPath SDK.
There are solutions (or hacks) out there but they all seem a bit "ugly". I really don't want any additional deployment steps to support my forms because it sort of takes the whole point away.
I gave up passing data to the form dynamically and figured that the Sharepoint site could have a configuration list that the form could look up to get the id I needed through the InfoPath Sharepoint adapter. Worked out great! Now my InfoPath form would display the data correlating to the id configured in the current Sharepoint Configuration List that I'd created and included in the site template.
Final problem was to make the form relate dynamically to the Sharepoint site on which it is deployed. This seems like a trivial feature. "I'm creating a form that uses contextual data from the current Sharepoint site, that's obviously possible" I thought. Assumptions is the mother of all fuckups.
You see, the url of the current site is accessible from script through the XDocument.Solution.URI property, but the SiteUrl property of the SharepointListAdapter is read-only.
Last resort was to modify the structural information of the form (manifest.xsf) with script. MSDN has a nice little article describing the process and I went ahead constucting XPath to manipulate my //xsf:dataObject/xsf:query/xsf:webServiceAdapter/xsf:operation/@serviceUrl through the XDocument.Solution.DOM property as instructed.
Guess what? When the Object Model property is readonly, so is it's xml based data. Trying to alter the text property of the nodes resulted in an exception saying "InfoPath cannot update the data because the form is currently read-only."
Great stuff. It is seemingly not possible to create site-relative dynamic InfoPath forms. Any form you make must be irreversably tied to the url entered at design time. I really wish someone proves me wrong here.
So what did we do? As of now, nothing. This is a frustration-outburst-post. My plan however is to reconstruct the entire logic of the form to include the standard Query View to retreive the data. We no longer deploy the form to multiple sites, but leave all forms in one location. This still forces us to redesign the form and rehook all connections each time we do another deployment of the site template. Sucks, but it's at least a one-time-per-deployment-affair. Then we save each instance of the form to the form library so that users only have to query once for each id. The rest of the time we can simply link to the existing xml file. Of course the form itself needs to include logic to show the query view only when no id is selected, but that's a breeze.