SharePoint Saturday Melbourne 2013

It's that time again!  I'm down in Melbourne for SharePoint Saturday later today on July 27. 

I'm presenting TypeScript and SharePoint, with updated notes as I have been working with TypeScript since Feburary.  It's been just awesome.

The SharePoint Saturday version of the presentation will be more developer focused, and I'm hoping my audience will come with their dev hat on and ready to play with JavaScript and TypeScript.

I'll update this post later to include the download files for the presentation.

See you at SharePoint Saturday.  Early night and early morning for me later.

 

Update

 

Again, I had a lot of fun in Melbourne, had a lot of fun discussions and talked to a number of you guys about TypeScript in the real world.  Drop me a line as you start to play with TypeScript in your own environment.

Happy Birthday shout out to Elaine van Bergen!

 

Downloads:

Australian SharePoint Conference 2013 Melbourne

Thank you attendees for yet another super conference.  It was quite a lot of fun presenting TypeScript for SharePoint.

 

I've got lots of feedback regarding the section on JavaScript - and have heard you guys loud and clear:

  • While the examples are fun...
  • But if you have other stuff to talk about, skip it!

I will miss talking about hoisting.  One of the craziest JavaScript gotchas there ever was.

 

VS.NET Extension

 

Downloads

ContentType Workflows not being updated in the Site Collection

 

This is a problem we've been seeing for a long time in our development and production server.  It is hard to describe the error, but there are a series of consequences.

  • We have reusable content type workflows defined for a InfoPath Form content type.
  • The Workflow Association is created at the root content type level and pushed down through the site collection, for every Forms Library that uses the content type.
  • Sometimes, we discover that an older version of the workflow is running, after we've updated the workflow. 
  • Next, we'll find that for some reason, for one specific Forms Library, the Workflow Association is still pointing to the old workflow template, so even when we manually start a new instance of a workflow, it is still running the older version.
  • In our specific case, the error was happening with Nintex Workflows, but this is not a Nintex Workflow problem - the problem is in the underlying SharePoint platform and how it is creating the workflow associations.

 

The Chase

 

I begin to write scripts to try to catch the form libraries that has this behaviour.  I worked out how to read the Workflow Association records.  For every workflow association, there is an InternalName field that looks like this:

  • [workflow name] <Cfg.{guid}>

When it is updated, the current workflow association is renamed to:

  • [workflow name (Previoius Version:{date}) <Cfg.{guid}>

Additionally, each Workflow Association has a BaseId that points to a BaseTemplate object, and the Template object has an Indexer Property

  • template["DeclarativeConfiguration"] - which gives back the same Cfg.{guid}

So a program (or script) can be written that looks through all the form libraries in our site collection, and report on content type workflow associations where the Cfg.{guid} on the Workflow Association doesn't match the one on the template.

 

UpdateAssociationToLatestVersion

 

Each Workflow Associations collection has a special method that will attempt to update the Workflow Associations to the latest version.  The method UpdateAssociationToLatestVersion will detect the Cfg difference, create a new Association to the latest template, rename the old Workflow Association to Previous, and set the old WorkFlow Association to continue running, but not start new instances.

 

The Error

 

I see a few scenarios.  When there is a workflow instance currently running, that seems to be when the Workflow Association for that Form Library breaks.

I also begin to watch SharePoint's Workflow Association table and notice that when a Workflow Association is broken, it seems to have a strange StatusFieldName "ows_" - this is for the Workflow Status column, but shouldn't be with that specific name.

image

 

Deep into the logs, I also see this exception buried:

Column 'ows_' does not exist. It may have been deleted by another user.

 

The Fix

 

Some quick search turns up Stefan Gossner's blog post from 2011.  Which describes the problem probably better than I could.  Essentially, when you have a lot of Lookup in your List View (remembering that each Workflow Status column is actually also a Lookup), it is possible for your List View Lookup Threshold throttling to break the code that creates new Workflow Associations.  When this exception happens, the existing Workflow Association is broken and must be manually removed and recreated.  And in the broken state, it will not Update to the latest version.

http://blogs.technet.com/b/stefan_gossner/archive/2011/05/20/error-message-quot-column-ows-does-not-exist-quot-when-updating-workflow-associations-on-a-list.aspx

image

 

The Aftermath

 

After we bumped the List View Lookup Threshold from 8 to 50, we are now able to update our Workflow Templates, and the correct Workflow Associations are being created and pushed down.  We still have a bunch of broken associations that requires attention and fixing, but at least we can identify them and correct them manually.

Very, very annoying problem, but it feels good to finally find the solution that has plagued us for months.

InfoPath - reading template.xsd in code for type checking

InfoPath is the world's most advanced XML-based form system.  Each InfoPath document is a fully structured XML file, and the template contains the XSD schema definition for the XML file.  This includes a bunch of information such as min/max occurrences, as well as the type information for each of the elements.

Because the information for the element's type is stored separately in the xsd file, it isn't possible at runtime to workout what the type of each element is supposed to be. 
When we are given:

  • my:value1

If we can't read the template.xsd file, we don't know if that's a number, a string, a datetime nor do we know if the field is nillable.  Some fields in InfoPath, such as the boolean and the datetime fields, can't be blank.  They have to be set to nil.

 

Here's how you can read the template.xsd in code

An InfoPath Form

 

Here is an InfoPath form with a few fields

image

 

The XML File Connection

 

Add a XML File Data Connection to an existing file in the template, I use "template.xml"

image

Save the template, and now drop into the code behind.

 

Code

public void InternalStartup()
{
    EventManager.FormEvents.Loading += new LoadingEventHandler(FormEvents_Loading);
}

public void FormEvents_Loading(object sender, LoadingEventArgs e)
{
    FileQueryConnection file = this.DataConnections["template"] as FileQueryConnection;
    file.FileLocation = "template.xsd";
    file.Execute();
    XPathNavigator template = this.DataSources["template"].CreateNavigator();
    string notes = "";

    foreach (XPathNavigator nav in this.CreateNavigator().Select("//*", this.NamespaceManager))
    {
        string localname = nav.LocalName;

        XPathNavigator element = template.SelectSingleNode("//*[@name='" + localname + "']", template);
        if (element != null)
        {
            notes += string.Format("{0} is of type {1} {2}; ", localname, element.GetAttribute("type", ""), element.GetAttribute("nillable", ""));
        }
    }

    this.CreateNavigator().SelectSingleNode("/my:myFields/my:notes", this.NamespaceManager).SetValue(notes);
}

  • The interesting part is at the top, where we bait and switch the FileQueryConnection to read the template.xsd schema file instead.  Because it is a valid XML file, InfoPath will read it happily.
  • We can then map any field in the main datasource to the corresponding definition in the template, and pull out the additional metadata such as type or nillable.

 

Result

image

 

Download

3-step fix Nintex WorkflowDesigner.aspx with your custom system masterpage

Scenario

  • You have created a wonderful, responsive-design, HTML5 MasterPage for your SharePoint 2010.  It works really well. 
  • You even did a variation for the system pages.  Those also work very well.
  • Until you try to use Nintex's Workflow Designer.  That page bombs out.   Most of the panels don't work, the scrollbars don't work.  The hovers go off screen. 
  • Your heart sank.

 

Your choices

  1. Easiest choice, if you don't have time, is to use v4.master for your system pages.  The biggest problem with this choice is the jarring experience your advanced users will get when they inevitably ends up on a system page and suddenly they are dropped into Vanilla SharePoint zone.
  2. Hardest choice, if you do have the time, is to butt your head against Nintex's WorkflowDesigner page until you win.  I have done this twice in the last two years.  In general, if you start with http://startermasterpages.codeplex.com/ you aren't too bad.  You'll need to pull a few ContentPlaceHolder panels out of hiding, and add a few elements with very specific ID's into your current navigation menu. 
    This will take you...  about 2 days. I won't go into the details of what you will face.
  3. Oh, and God have mercy on your soul.
  4. This blog entry is about an Interesting third choice.  You can hack Nintex's WorkflowDesigner.aspx file to use v4.master, while all your existing system pages will continue to use your new custom masterpage.

 

Consequences

  • Nintex's WorkflowDesigner.aspx is an application page that resides in _layouts folder on each Web Front End.  You will need to apply this change across all your WFE manually.
  • When Nintex updates Nintex Workflow, you may need to re-apply this hack.
  • This hack applies to ALL nintext solutions across the entire WFE.  For all  web applications, site collections.

 

How to fix (hack)


Understand the consequences, the hack is actually REALLY simple

  1. Browse to C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\NINTEXWORKFLOW\
    Copy this file and make a backup:  WorkflowDesigner.aspx
  2. Open it and find the masterpage reference: 
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WorkflowDesigner.aspx.cs" Inherits="Nintex.Workflow.ApplicationPages.WorkflowDesigner,Nintex.Workflow.ApplicationPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=913f6bae0ca5ae12" DynamicMasterPageFile="~masterurl/default.master"  %>
  3. Change DynamicMasterPageFile to MasterPageFile="../v4.master"
    The v4.master sits in \LAYOUTS\v4.master by default making this hack really easy.

 

Result

  • Your custom system masterpage
    image
  • Nintex WorkflowDesigner running on v4
    image