Showing posts with label InfoPath. Show all posts
Showing posts with label InfoPath. Show all posts

Thursday, September 27, 2012

A Farewell to Groove

I've been trying to keep an eye on the Office 15 rollout. Less concern in mind over the new applications and more about the implications they have for SharePoint. I'd heard from Becky Isserman that my trusty old friend InfoPath was getting barely a manicure, let alone a full makeover, but it seems that this is not quite correct.

http://msdn.microsoft.com/en-us/library/office/aa947697(v=office.15)

Lots of new web controls supported, sandboxing, full support for Visual Studio. Heck, all we really need is support for Managed Metadata and we're golden. I can't imagine why we're dragging our feet for so long on that, but c'est la vie.

Now then, as Redmond giveth, Redmond taketh away...

http://www.brainlitter.com/2012/07/28/rip-sharepoint-workspace-in-2013-we-hardly-knew-ye/

Groove is finally dead. A single tear rolls down Ray Ozzie's cheek. Apparently this functionality is to be replaced with SkyDrive and SP2013 integration. We'll have to see how that works exactly, but if the offline support is as-advertised (because that always happens!), then we might just be hurrying to SP2013 sooner rather than later.

Monday, March 19, 2012

IPFS permissions in SP2007 versus SP2010

The more things change, the more things stay the same. With regards to changing wantonly, I expect.
03/19/2012 09:16:04.25 w3wp.exe (0x0DFC)                       0x1BF8 SharePoint Foundation         Logging Correlation Data       xmnv Medium   Name=Request (POST:https://my.site.com:443/path/to/site/_layouts/Postback.FormServer.aspx) dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.29 w3wp.exe (0x0DFC)                       0x1BF8 SharePoint Foundation         General                       8kh7 High     <nativehr>0x80070005</nativehr><nativestack></nativestack>Access denied. dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.29 w3wp.exe (0x0DFC)                       0x1BF8 SharePoint Foundation         Logging Correlation Data       xmnv Medium   Site=/ dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.30 w3wp.exe (0x0DFC)                       0x1BF8 InfoPath Forms Services       Runtime                       f9n5 Medium   Thread was being aborted. dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.30 w3wp.exe (0x0DFC)                       0x1BF8 InfoPath Forms Services       Runtime - Business Logic       7tge Medium   Exception thrown from business logic event listener: System.Threading.ThreadAbortException: Thread was being aborted.     at NonConformanceReport.FormCode.buttonInitialSave_Clicked(Object sender, ClickedEventArgs e) in D:\2010 Projects\NonConformanceReport\NonConformanceReport\FormCode.cs:line 458     at Microsoft.Office.InfoPath.Server.SolutionLifetime.ButtonEventHost.<>c__DisplayClass6.<>c__DisplayClassa.<add_Clicked>b__3()     at Microsoft.Office.InfoPath.Server.Util.DocumentReliability.InvokeBusinessLogic(Thunk thunk)     at Microsoft.Office.InfoPath.Server.SolutionLifetime.ButtonEventHost.FireClickedEvent(Document document, ClickedEventArgs args)     at Microsoft.Office.InfoPath.Server.DocumentLifetime.OMExceptionManager.CallFormCodeWithEx... dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.30* w3wp.exe (0x0DFC)                       0x1BF8 InfoPath Forms Services       Runtime - Business Logic       7tge Medium   ...ceptionHandling(UserMessages userMessages, OMCall d) dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.30 w3wp.exe (0x0DFC)                       0x1BF8 InfoPath Forms Services       Runtime                       f9n5 Medium   Thread was being aborted. dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.30 w3wp.exe (0x0DFC)                       0x1BF8 InfoPath Forms Services       Runtime                       961x Medium   Not persisting state for request due to previous errors. Form Template: urn:schemas-microsoft-com:office:infopath:Non-Conformance-Report:-myXSD-2011-02-18T16-16-58 dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.33 w3wp.exe (0x0DFC)                       0x1BF8 InfoPath Forms Services       Runtime                       82fh Exception Unhandled exception processing request for PostbackPage Microsoft.Office.InfoPath.Server.Util.InfoPathFatalException: Exception of type 'Microsoft.Office.InfoPath.Server.Util.InfoPathFatalException' was thrown.     at Microsoft.Office.InfoPath.Server.Util.GlobalStorage.get_CurrentFormId()     at Microsoft.Office.InfoPath.Server.Util.GlobalStorage.get_CurrentContext()     at Microsoft.Office.InfoPath.Server.Util.GlobalStorage.IsDefined(GlobalItems key)     at Microsoft.Office.InfoPath.Server.Controls.DateFormattingInfo.TryGetCachedTimeZoneId(UInt16& timeZoneId)     at Microsoft.Office.InfoPath.Server.Controls.DateFormattingInfo.GetSPTimeZoneObject()     at Microsoft.Office.InfoPath.Server.Controls.DateFormattingInfo.CalculateSPLocalTimeOffset()     at Microsoft.Office.InfoPath.Server.Util.G... dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.33* w3wp.exe (0x0DFC)                       0x1BF8 InfoPath Forms Services       Runtime                       82fh Exception ...enericUtils.GetServerTimeZone()     at Microsoft.Office.InfoPath.Server.DocumentLifetime.ErrorPageRenderer.RenderResult(TextWriter writer, Document document, EventLogStart eventLogStart)     at Microsoft.Office.InfoPath.Server.DocumentLifetime.ErrorPageRenderer.RenderForException(HttpContext context, Exception exception, Document document, EventLogStart eventLogStart)     at Microsoft.Office.InfoPath.Server.Controls.PostbackPage.OnPreInit(EventArgs e)     at System.Web.UI.Page.PerformPreInit()     at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.33 w3wp.exe (0x0DFC)                       0x1BF8 SharePoint Server             Unified Logging Service       c91s Monitorable Watson bucket parameters: SharePoint Server 2010, ULSException14, 41b7c39f "infopath forms services", 0e00178d "14.0.6029.0", fd34ba92 "microsoft.office.infopath.server", 0e0017dd "14.0.6109.0", 4e41890c "tue aug 09 15:22:52 2011", 00002563 "00002563", 00000014 "00000014", 33bcb602 "infopathfatalexception", 38326668 "82fh" dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.33 w3wp.exe (0x0DFC)                       0x1BF8 SharePoint Foundation         Performance                   nask High     An SPRequest object was not disposed before the end of this thread.  To avoid wasting system resources, dispose of this object or its parent (such as an SPSite or SPWeb) as soon as you are done using it.  This object will now be disposed.  Allocation Id: {C5772F5B-A52E-4B26-B3BE-1A21B271E91E}  To determine where this object was allocated, set Microsoft.SharePoint.Administration.SPWebService.ContentService.CollectSPRequestAllocationCallStacks = true. dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.33 w3wp.exe (0x0DFC)                       0x1BF8 SharePoint Foundation         Performance                   nask High     An SPRequest object was not disposed before the end of this thread.  To avoid wasting system resources, dispose of this object or its parent (such as an SPSite or SPWeb) as soon as you are done using it.  This object will now be disposed.  Allocation Id: {A0ED4F51-D0BF-44DF-A58F-C3CEC59FA780}  To determine where this object was allocated, set Microsoft.SharePoint.Administration.SPWebService.ContentService.CollectSPRequestAllocationCallStacks = true. dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.33 w3wp.exe (0x0DFC)                       0x1BF8 SharePoint Foundation         Performance                   nask High     An SPRequest object was not disposed before the end of this thread.  To avoid wasting system resources, dispose of this object or its parent (such as an SPSite or SPWeb) as soon as you are done using it.  This object will now be disposed.  Allocation Id: {EF332EFB-A193-4C02-BCD1-D7354B478B84}  To determine where this object was allocated, set Microsoft.SharePoint.Administration.SPWebService.ContentService.CollectSPRequestAllocationCallStacks = true. dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
03/19/2012 09:16:04.33 w3wp.exe (0x0DFC)                       0x1BF8 SharePoint Foundation         Monitoring                     b4ly Medium   Leaving Monitored Scope (Request (POST:https://my.site.com:443/path/to/site/_layouts/Postback.FormServer.aspx)). Execution Time=84.2051154546178 dd4f6a8d-fcc4-463b-b42c-f3c150b42ca6
In SharePoint 2007, using an IPFS form meant that the user account needed whatever privileges were required to:
  1. Open the form template
  2. Access any data sources referenced in the form template
  3. Save the form back (if necessary or not handled in code, the form might not save to SP at all!)
Reasonable enough. Since the form templates are stored in the site collection root, if you had forms deployed in a subsite, you would just create a SP/AD group that holds the form users and gives them the specific access they require without compromising your model.

This translates to:
  1. Read access to the site collection root (from which FormServerTemplates should be inheriting)
  2. Read access to any data sources referenced in the form template
  3. Add or Modify access depending on if/how the form saves data back to SharePoint
So, obviously with SharePoint 2010, things get more complicated. Some of the users of two particular applications no longer have the ability to save a specific form. Of course, this didn't come up in our migration testing. Now I find that the following is required:
  1. Read access to the site collection root (from which FormServerTemplates should be inheriting)
  2. Contribute access to the web root
  3. Read access to any data sources referenced in the form template
  4. Add or Modify access depending on if/how the form saves data back to SharePoint
I cannot fathom why this changed, but now it's forcing me to either make broad, sweeping security changes to accomodate the forms, or place them in a subsite and keep security as-is, but fix any broken path dependencies (such as Excel sheets reporting on form submissions).


Edit: I haven't had time to do isolation testing to narrow down the above, but I had another form that works without setting Contribute on the site root, the key difference being that this form uses the built-in SharePoint submit rule rather than saving via code. I'll have to take a closer look at it.

Monday, February 27, 2012

IPFS in SharePoint 2010

So, in my old work environment, we had a number of rather elaborate code-behind forms hosted in IPFS. My boss there made a wise decision to keep those applications running in MOSS while gradually porting those solutions into SP2010. I was dimly aware of the fact that porting IPFS 2007 forms into SP2010 was effectively a game of roulette, so I was pleasantly surprised when the three forms we currently use at my new company ported with some degree of ease.

Ironically, the form with the most code-behind (for item uploads, sending mail notifications, rolling comments in a repeating section, and a host of other tidbits) had no problems whatsoever. The form that I experienced the biggest number of issues with had almost no code at all, and the code it did have was simply an autonumber generation system.

This form uses a drop-down category selector that, when changed, would show/hide a number of other drop-downs based on the category selected. In the past, each of these categories was located in its own section with duplicate bindings to the same parent group (I'm not a huge XML guy, so I have little doubt that this is highly offensive to someone). So, when you change the category, one section unhides, and the currently visible one disappears. The sub-selections each use a OWSSVR.dll query to filter on a specific list using the category selection as a parameter, so we have a different data source for each category. Simple enough (but not really). I could have managed this in code-behind to a degree, but I'm not a fan of using OnFormXmlChange events in IPFS, and I didn't want the user to have to click a button after selecting a category to re-run the lookups.

Anyway...

Further down this form lie a number of XHTML fields.

For some inexplicable reason, whenever the category selection changes (either in a new form, or changing the selected value in an existing form), one or more of these XHTML fields would suddenly become read-only (and any existing text would be concealed).

Flailing away at the form template like a coffee-dependent monkey eventually gave rise to the realization that in SP2010, upon form redraw (as might happen if a control is being shown or hidden), the fields are actually being reloaded and their contents re-rendered, and it seems as though having to redo this redraw effort with the extra sections caused the redraw to fail prematurely, and so some controls would not completely load.

At first I experimented with cloning the category drop-down into a series of radio selectors. Using these made the problem less prominent, but it would still occur. Finally, I removed the sections and placed each of the six sub-selects into a single section and set the conditional formatting on each control itself, rather than a governing section, and in general this made the behavior go away (though it still manifests when the Category selection changes, the redraw seems to finish when the sub-selection is changed).

I met with the owner of the system employing this form today to show him my work in redesigning the original work to conform to my new IPFS form layout (since I had to touch the form anyway to fix the 2010 issues, I modified its layout to conform to the styling I plan to employ for all my forms here). During our demo, we came across another issue.

Now, cascading drop-downs are nothing new in InfoPath, but the behavior of these in IPFS 2010 is a little different and might cause me some grief down the road. Normally, any data source queries in InfoPath lookups will always have a blank entry at the top of the query. I have a rule set to reinitialize the value in this sub-select if the category changes (since obviously that value is no longer valid). When the category changes, the drop-down does indeed clear, however the previous selection is still shown in the drop-down's values! What exactly is going on here?

Clearly there's a new renderer at work to go along with the SP2010 engine, but I'm puzzled by some of these not-particularly-complex bugs popping up (and unfixed in Service Pack 1). We're currently planning to fast-track our migration into SP15 (possibly even skipping the SP2010 visual upgrade!), so maybe I should just hold my breath for a year.

Thursday, September 22, 2011

Centrally-managed InfoPath data connection libraries

Call it laziness if you will. I never got around to testing the use of InfoPath data connections in a centrally-managed library. I hadn't given much consideration to the benefits of placing UDCs there instead of a Data Connection library.

Well, I tried it for the first time yesterday, and wow, there's one really really large benefit - it's MUCH faster than placing them in document libraries. I assume there's some overhead having to do with checking permissions, plus there's likely a dedicated service path to get centrally-managed UDCs whereas I expect InfoPath uses the List service to fetch them in IPFS forms. In my old environment, when opening new forms that had list data connections that load on initialization, form launch would often take 5-10 seconds, whereas now it's a tenth of that.

I hope this performance holds out in 2010! Now, if only the administration/management of those UDCs was more refined...

Wednesday, December 8, 2010

Using XmlFormHostItem.Errors for validation

When I first started out developing in InfoPath, I frequently used conditional formatting to satisfy business rules in forms. Did you not fill out the city field in your address? Can't hit the Submit button! It was effective, though not very workable with end users who wouldn't necessarily know what fields they missed. Furthermore, what if I was pre-loading data on initialization and the form was missing a hidden required field?

Now I use XmlFormHostItem.Errors, or simply Errors. Errors is FormErrorCollection object which contains all the FormError instances in your form, which includes both required fields that have not been filled in and also Data Validation failures. You can iterate over the errors and report them back to the user, dump them to trace/logging, whatever you want to do. I usually keep a hidden section which is tied to a boolean value in the main dataset and if the form submission fails to validate, the boolean is set to true and the note appears, advising the user to double-check the form for required fields.

You sometimes will have to get creative in handling some controls that don't support Data Validation. For example, a form I have been working on requires the user to provide at least one file attachment for documentation of a request. The file attachment control of course doesn't support Data Validation, nor does the Button control. In these cases, I'll put the control in a new section (provided it isn't in one already), manually apply a bright red asterisk in text adjacent to the control in one section, and use conditional formatting to show the section with the asterisk until the condition has been satisfied.

Ooh, are we using conditional formatting to handle business logic again? No matter - to go along with it, I'll create a new text field in the schema, insert that field in one of the two sections, and put the data validation on *that* field. Now I just have to use that control as a proxy for the validation. For example, once my code has handled the file attachment, I'll also set the value of this proxy field in code, and the data validation will be satisfied.

Simple and elegant, and also far easier to troubleshoot when issues arise.

Minor gotcha with owssvr URL queries

Sorry for the lack of posting recently, I had to gear up quickly for a relocation, and now that I'm mostly settled in my new house, it's time to get back on track!

I encountered an issue today in some forms I've been working on. I was using a URL query into SharePoint to get an XML-formatted subset of list items from a SharePoint list. If you're unfamiliar with this, you can essentially use a URL in the following format to get an XML-formatted chunk of data from SharePoint and process it however you like:

http://webroot/sites/sitecollection/_vti_bin/owssvr.dll?Cmd=Display&List=GUIDofSharePointList&XMLDATA=TRUE&FilterField1=ColumnTitle&FilterValue1=Whatever&FilterField2=AnotherColumnTitle&FilterValue2=Stuff

I have an InfoPath form that's using this to populate a drop-down list. We'd never expected this list to get long, but the business unit involved grew this list from 15 entries to more than 120 in between versions, and I suddenly found that the list was not returning all the items.

It turns out that the data returned using this method is partially affected by the settings for the Default View for that list. The default setting for SharePoint views usually limits list output to batches of 100. I upped this to 1000, and now I get all my list items. Fantastic!

Tuesday, October 26, 2010

Hybrid InfoPath forms (client/hosted)

I'm working on writing up a post detailing my experiences with one of the issues which originally motivated me to start this site. Essentially, one of the forms that I inherited recently is a monolithic monster which is used in both IPFS and in InfoPath 2007 (eg - the desktop client).

There are a number of perils and issues pertaining to working in this mode that I've had to overcome and I'll talk about those very soon.

Wednesday, October 13, 2010

Visual Studio versus VSTA

In taking over the duties of another developer who did part-time InfoPath maintenance, I've also been presented with an opportunity to clean out some dusty code closets.

All of the forms I've touched during my time here are in Visual Studio projects, but we still have a few forms that I haven't been directly involved in which were developed exclusively in VSTA. This change of guard has presented me with the opportunity to bring these other forms into alignment with our existing codebase, which is nice.

The first time I tried to migrate a VSTA project to Visual Studio, it was a nightmare. Not knowing how InfoPath 2007 integrated with VS08, I frequently found myself checking in-and-out code to avoid the dreaded "Operation could not be completed" errors. I was actually surprised earlier this week when I was able to successfully migrate a project in under half an hour, complete with renaming some extensionless files in the manifest and schemas.

The first pointer I learned for this task is a fairly simple one. If Visual Studio won't open the form, navigate to the manifest.xsf file, right-click on it, and select to Design the form in InfoPath. If there's a schema error in the form, the InfoPath client will point you straight to it. Visual Studio will not.

This will only carry you so far, of course. If you have a non-critical file missing that is specified in the manifest (such as a datafile for a data source), InfoPath will load your form in Design mode while Visual Studio will fail. Visual Studio also likes to complain when it can't get exclusive file locks on every file specified in your manifest.xsf, and accordingly, Visual Studio will refuse to open those files if the embedded InfoPath client is loaded (which also means that text searches will exclude those files!). Better keep that copy of Notepad2 handy.

Additionally, should Visual Studio lose its file lock on *any* of those files opened during Design mode, it will refuse to save any further changes, so save often!

This certainly seems like a lot of misery, but it's the best way to handle TFS integration, and it offers better debugging than you'll get out of VSTA, so it's a necessary evil. If you're prepared upfront and get some experience under your belt, it doesn't have to be a nightmare.