Saturday, September 25, 2010

Debugging Error upon creating MySite

In a SharePoint intranet, feature stapling is applied to the standard MySite site definition to customize and extend the newly created employee’s MySite’s. After making some requested changes to the custom MySite masterpage, I deployed the SharePoint solution to the development farm. When validating that upon first visit an employee’s MySite is still successful and correct created, I got a runtime error. The display error message gave no details on the problem cause, and in the 12hive log no related information was found. Due a lack of rights to open the EventLog on the remote development server, I could not [myself] check whether in there useful logging was available.
So, what to do? Due the nature of my changes I was pretty sure that the malfunction could not be related back to them. But pretty sure is not good enough, when the ultimate deployment target is the company production intranet. I needed to exactly pinpoint the problem cause, and proof that it was not related to my deployment.
The SharePoint standard MySite creation handling hides the details of the thrown and catched exceptions. To detect what exception was thrown, I therefore created my own DebugMySite.aspx, and filled it with the basics of the standard MySite creation handling – with the noticeable difference to expose the exception details within the browser. Via this debugging approach I learned that the internal error message reported the following:
My Site creation failure for user '<domain>\<username>' for site url 'https://SharePointServer/personal/<username>'. The exception was:
Microsoft.Office.Server.UserProfiles.PersonalSiteCreateException: There has been an error creating the personal site ---> System.ArgumentException: Value does not fall within the expected range.
at Microsoft.SharePoint.Library.SPRequestInternalClass.SscCreateSite(Guid gApplicationId, String bstrUrl, String bstrServerRelativeUrl, Int32 lZone, Guid gSiteId, Guid gDatabaseId, String bstrDatabaseServer, String bstrDatabaseName, String bstrDatabaseUsername, String bstrDatabasePassword, String bstrTitle, String bstrDescription, UInt32 nLCID, String bstrWebTemplate, String bstrOwnerLogin, String bstrOwnerUserKey, String bstrOwnerName, String bstrOwnerEmail, String bstrSecondaryContactLogin, String bstrSecondaryContactUserKey, String bstrSecondaryContactName, String bstrSecondaryContactEmail, Boolean bADAccountMode)
at Microsoft.SharePoint.Library.SPRequest.SscCreateSite(Guid gApplicationId, String bstrUrl, String bstrServerRelativeUrl, Int32 lZone, Guid gSiteId, Guid gDatabaseId, String bstrDatabaseServer, String bstrDatabaseName, String bstrDatabaseUsername, String bstrDatabasePassword, String bstrTitle, String bstrDescription, UInt32 nLCID, String bstrWebTemplate, String bstrOwnerLogin, String bstrOwnerUserKey, String bstrOwnerName, String bstrOwnerEmail, String bstrSecondaryContactLogin, String bstrSecondaryContactUserKey, String bstrSecondaryContactName, String bstrSecondaryContactEmail, Boolean bADAccountMode)
at Microsoft.SharePoint.Administration.SPSiteCollection.Add(SPContentDatabase database, String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String secondaryContactLogin, String secondaryContactName, String secondaryContactEmail, String quotaTemplate, String sscRootWebUrl, Boolean useHostHeaderAsSiteName)
at Microsoft.SharePoint.SPSite.SelfServiceCreateSite(String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String contactLogin, String contactName, String contactEmail, String quotaTemplate)

With these error details, I could do a focussed search on the internet. And found this related forum-entry Error creating MySite: There has been an error creating the personal site, which had the answer: "add the account configured as the Application Pool Identity for the web site to the "Farm Administrators" group through the Central Administration pages". This was the situation earlier for the intranet webapplication on our development farm, but somehow this got broken. With this knowledge I went to our IT pro, and asked them to restate the AppPool identity as a farm admin, followed by an IISReset. After that, the MySite creation problem was solved.

Saturday, September 4, 2010

Duet Enterprise - Technical Overview presentation

Upon searching on 'Duet Enterprise', I came accross this posted presentation with technical overview. Next to the expected high-level on the Duet Enterprise proposition, this powerpoint also contains some more in-depth explanatory visualizations of the technical and system flow in capabilities like authorization and single sign-on, SAP role based authorization, workflow, monitoring.
Note, the presentation is [declared] prelimary; in awaiting of RTM.

Thursday, August 26, 2010

More [functional] robustness issues with OOTB InfoPath Forms Services

Earlier I blogged about some robustness issues I encountered with the application of InfoPath Forms Services in an external facing SharePoint site. The basis of the framework developed in that project is re-used in context of the company's intranet. Hereby I ran into some new robustness issues. I'll describe them here, and also the outline of the applied solutions.

  1. Placing XmlFormView webpart on a SharePoint page conflicts with inline server codeblocks in MasterPage
    Immediately upon adding the out-of-the-box Microsoft.Office.InfoPath.Server.Controls.XmlFormView webpart on a publishing page in the company's intranet, SharePoint throwed an exception:
    Source: System.Web
    Message: The Controls collection cannot be modified because the control contains code blocks (i.e. ).
    Stacktrace:
    at System.Web.UI.ControlCollection.Add(Control child)
    at Microsoft.Office.InfoPath.Server.SolutionLifetime.ScriptIncludes.AddCssLinkToHeader(HtmlHead head, String href)
    at Microsoft.Office.InfoPath.Server.Controls.XmlFormView.TryToAddCssLinksToHeader()
    at Microsoft.Office.InfoPath.Server.Controls.XmlFormView.OnDataBindHelper()
    at Microsoft.Office.InfoPath.Server.Controls.XmlFormView.OnPreRender(EventArgs e)
    at System.Web.UI.Control.PreRenderRecursiveInternal()
    at System.Web.UI.WebControls.WebParts.WebPart.PreRenderRecursiveInternal()
    at System.Web.UI.Control.PreRenderRecursiveInternal()
    at System.Web.UI.Control.PreRenderRecursiveInternal()
    at System.Web.UI.Control.PreRenderRecursiveInternal()
    at System.Web.UI.Control.PreRenderRecursiveInternal()
    at System.Web.UI.Control.PreRenderRecursiveInternal()
    at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint

    First analysis learned that the problem was related to the applied SharePoint MasterPage: it manifested itself with 2 of our custom MasterPages, but not on other custom nor the standard (Publishing) Masterpages. Inspection of the particular custom MasterPages disclosed the following server-side code:
    <% Response.Write("<script>var Collaboration_SiteRelativeUrl='" + SPContext.Current.Site.Url + "';</script>"); %> 

    The inclusion of this inline server codeblocks resulted in the conflict with the server-side operation of the XmlFormView webpart. The solution was to replace the inline server codeblocks-tags '<%' and '%>' approach by a HtmlHead (which is a webcontrol) databinding approach:

    <script>var Collaboration_SiteRelativeUrl="<%# SPContext.Current.Site.Url %>";</script> 

    And in the MasterPage codebehind:

    protected override void OnLoad (EventArgs e)
    {
        base.OnLoad(e);
        Page.Header.DataBind();




  2. IE 6 gives a runtime Javascript error in case of RichTextBox control on the form
    While demonstrating the potential of the self-service WebForms functionality to internal stakeholders, I was asked to modify an earlier published InfoPath form with the placement of a RichTextBox control. After re-publishing the InfoPath form to the SharePoint target site, the form still correctly displayed in the content page; including the added RichTextBox control. However, when positioning the mouse in the RichTextBox control, the IE6 browser (Red: still the company's standard) reported a runtime Javascript error. Also the RichTextBox toolbox was not displayed, leaving the control pretty useless wrt a plain TextBox control.

    With these problem symptons, I kinda got a 'Deja-Vu' feeling. It looked very much like the problem earlier encountered with displaying InfoPath forms in IE 6. And indeed: via Javascript debugging I detected that the client-side runtime error manifested itself in the same OOTB InfoPath Inc/Core.js method as before: ErrorVisualization.ComputeAbsoluteTop(). Was then the problem caused by the usage of relative CSS-positioning applied in the custom branding, this time it proved completely InfoPath related. I could easily reproduce the same problem within a standard SharePoint WebPart page, with a standard MasterPage. The explanation of the IE 6 Javascript problem is in the HTML that InfoPath Forms Services renders for a RichTextBox control: an embedded iframe element within the DOM document. Due to the fault behaviour of the IE 6 offsetParent method implementation in combination with the non-robust/error-prone implementation of the OOTB InfoPath method, this results in the runtime Javascript error.The solution was to runtime at browser/client-side expand that OOTB InfoPath method to make it robust for the IE 6 faulty CSS offsetParent implementation.





  3. InfoPath re-publishing adds duplicate site columns to the ContentType

    Upon re-publishing an InfoPath formtemplate during the demonstration, I noticed another issue. It looked as if all promoted fields in the ContentType were now duplicate present. A quick internet search learned that this is a known InfoPath feature/behaviour, just something I myself was not aware of upto now. And neither something I was particular happy with. I think it is pretty ridiculous to add a complete other set of fields to the InfoPath ContentType each time you re-publish the associated formtemplate. You have some control-options in the InfoPath publishing wizard to prevent the creation of another set of promoted fields, but this is manual-dependent and thus error-prone; let alone it is also very cumbersone and clumsy for the functional managers (the first-class users of the self-service WebForms functionality in the company portal). Therefore I sought for a manner to afterwards correct the modified ContentType, by removing all duplicate FieldLinks. Ideally did would be done fully automatic in the scope of the InfoPath publishing, and thus transparent and invisible to the WebForms functional managers. Sadly, SharePoint does not have an EventReceiver signalling the creation or update of a ContentType. The solution is therefore to deliver a custom SharePoint application page via which the WebForms functional manager can afterwards fix the InfoPath modified ContentType. He/she selects in the dropdown the ContentType that [potentially] needs a cleanup. The custom application page then inspects
    the FieldLinks in the ContentType for duplicate occurences, and removes each one found. The changes (deletions) in the SiteCollection ContentType are propagated to all childs. Also each duplicate detected FieldLink is removed from the Fields collection of each SPDocumentLibrary that is associated with the selected InfoPath ContentType (code snippet).

Thursday, August 12, 2010

Handling save conflict within SPList EventReceiver

Background

Publishing an InfoPath form to a SharePoint site creates a new contenttype in the site. Via the InfoPath publishing wizard you have some control over the structure of the created contenttype. But in essence the control is very limited when compared with explicitly provision a contenttype yourself [see also previous post Administrate data from InfoPath form in a self-provisioned ContentType for further explanation why I prefer this above the automatic created information architecture entities]. However, it is not always possible or viable to explicit provision the InfoPath utilized IA entities. The big selling point of InfoPath is that it enables self-service (web)form-definition by functional management. A key cornerstone in this self-services proces is the InfoPath publishing functionality to allow functional managers to themselves distribute the InfoPath forms to a SharePoint site.
One of the aspects missing with the InfoPath publishing managed contenttypes is including the InfoPath promoted fields in the display form. Displaying all InfoPath form fields is in particular handy when quickly browsing the data submitted to a SharePoint forms library.

Solution approach

To fix the functional shortcoming requires to afterwards make the promoted fields displayed. This is not something you want to burden the functional managers with. The aim is therefore to execute it automatically in the context of the target SharePoint site. The ideal moment would be when the InfoPath managed contenttype is created or updated. SharePoint however does not provide an eventreceiver for these events. The next best moment is when the contenttype is associated with the forms library to which the InfoPath form data is submitted. Here you neither have a direct event notifying the contentype association. But you can receive indirect notification via SPListEventReceiver::FieldAdded. The idea is then to check each added field whether it is an InfoPath promoted field, and if so to alter its definition so that the field will appear in the standard SharePoint display form.

Issues encountered

So, easily said and done. Associate the custom ListTemplate with a SPListEventReceiver, and fill in the FieldAdded method. In my local development image it worked like a charm: after you associate via the SharePoint GUI a document library with an InfoPath contenttype, all promoted fields of that contenttype appear in the document library display form. But after deploying to the central SharePoint development farm, I ran into the first issue. Upon associating a library with a contenttype, SharePoint faulted with a weird message: The specified program requires a newer version of Windows.
Despite this misleading error message, it was immediate clear that the issue was caused by the custom FieldAdded eventhandler:
Apparently, SharePoint does not allow to update a list field in the runtime context of that field being added to a list.

Solution outline

Solution is to isolate the execution of the field-update from the field-addition runtime context. Instead of direct updating the field, schedule this work via a worker thread. One extra aspect to take into account is that the scheduled worker threads can still run into a parallel update conflict:

Save Conflict

Your changes conflict with those made concurrently by another user. If you want your changes to be applied, click Back in your Web browser, refresh the page, and resubmit your changes.

  at Microsoft.SharePoint.Library.SPRequest.UpdateField(
        String bstrUrl,String bstrListName, String bstrXML)
  at Microsoft.SharePoint.SPField.UpdateCore(Boolean bToggleSealed)
  at Microsoft.SharePoint.SPField.Update()
  at WebformulierFieldsHandler.Worker.b__1()
 

The likelihood of these save conflicts increases with the number of promoted fields in the contenttype, and can already manifest itself when that number is 4 to 5. It can be made functional robust by implementing a retry mechanism in the worker thread.

Wednesday, August 4, 2010

What about the competition - new roadmap for SAP NetWeaver Portal

As a SharePoint adept, I don't really consider the SAP Enterprise Portal as competition. Let's face it, the typical UI is horrible, and it lacks many of the capabilities the SharePoint platform brings. But moreover, the impression [within the market] is that SAP has stopped with actual new major developments in this product (Web2.0, content management, social media). SAP is putting it's intellectual resources and budget mainly on the business capabilities, and less on fancy user interaction. Fair enough, as it leaves room for integration and interoperability via foreign UIs, as SharePoint.
Contradicting the above, it's knownable that at SAPPHIRE some new additions for SAP NetWeaver Portal were announced. Most notable the concept of 'Enterprise Workspaces'. Read and see more of this in SAP NetWeaver Portal – SAPPHIRE NOW Summary.
It aims to provide SAP users with an iGoogle- or myYahoo-type experience within SAP, allowing them to build their own pages with structured and unstructured assets -- reports, RSS feeds and so on. It applies a self-service approach within defined roles and security. [SAP NetWeaver Portal roadmap includes 'Workspaces,' easier third-party integration]
Well, the UI impressions and the self-service concepts are rather impressive and promising. I do hold on to my opinion that SharePoint is a better overall portal platform. But it looks as if SAP could be making a new step forward in its own portal product.

Thursday, July 29, 2010

Standards-Based Interoperability between SAP NetWeaver 7.0 and Microsoft .NET 3.5/4.0

Microsoft opened a new interoperability area within MSDN on Web Service Interoperability between the major web services vendors. Amongst these naturally also SAP. The site contains an extensive (75 pages) Demonstration Scenario of the Collaboration Technology Support Center addressing information about how to set up standards-based Web services communication between Microsoft .NET Framework applications and SAP Application Server ABAP-based consumers and providers.

Wednesday, July 28, 2010

Portal Embedding of SAP UWL into SharePoint

There are multiple alternatives for utilizing SharePoint as presentation layer to SAP functionality. The most basic is portal launch, next comes portal embedding. Portal embedding has some advantages (mainly being rapidly to achieve: you only visually integrate the 2 [SAP, Microsoft] environments, without any direct systems/applications integration and interoperability), but remains a rather poor man's approach to portal integration. The typical SAP UI / Look and Feel is very different from the SharePoint UI (standard or company-customized), and the SAP Portal pages exhibit themselves browser navigation in addition to the SharePoint navigation.
Andre Fischer a.o. from SAP recently published the whitepaper Integration of SAP Universal Worklist into Microsoft Office SharePoint. This paper contains an example of the portal embedding approach, while also addressing the double navigation issue. In particular it describes an approach to integrating the SAP Universal Worklist into SharePoint context. Basically it comes down at making sure at the SAP Portal side that the portal pages are rendered headerless, without the portal navigation. The elegance of the sketched approach is that it is limited to SAP Portal configuration and customization work, there is no custom development required at either SAP nor SharePoint side.