Tag: Nintex

Nintex – Specified value is not supported for the urlOfFile parameter

Recently after a Ninxtex migration/version update we encountered the following error when trying to publish any workflow:

Windows Event Log Error:
System.ArgumentException: urlOfFile Parameter name: Specified value is not supported for the urlOfFile parameter.
at Microsoft.SharePoint.SPFileCollection.get_Item(String urlOfFile)
at Nintex.Workflow.WorkflowRepository.NameInUse(String workflowName, Guid listId, WorkflowType& workflowType)
at Nintex.Workflow.ApplicationPages.SetName.Page_Load(Object sender, EventArgs e)
at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at Microsoft.SharePoint.WebControls.UnsecuredLayoutsPageBase.OnLoad(EventArgs e)
at Microsoft.SharePoint.WebControls.LayoutsPageBase.OnLoad(EventArgs e)
at Nintex.Workflow.ServerControls.NintexLayoutsBase.OnLoad(EventArgs e)
at Nintex.Workflow.ApplicationPages.SetName.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

To resolve this, go to the hidden NintexWorkflows library and check the contents of each subfolder. If your site is http://farm/sites/test the URL would be http://farm/sites/test/NintexWorkflows. If any subfolder is empty (contains no files), delete the subfolder – you should be able to publish after that.

SpSite in Nintex Workflow Custom Action

So today I needed to get the URL of the current SharePoint site my Nintex Custom Action Visual Studio solution is executed under, using the SPSite class. Problem was, was not working on the server of the SPSite. Nor would I want to have to install Visual Studio on the production instance where the solution was to live.

Makes sense, just need to grab the httpcontext. SPContext.Current.Site seemed to fit the bill, but alas, it did not work. Lost some time hunting for a solution to the following error:

Could not create activity of type 'CustomActions.MyCustomActivity'. System.IO.FileNotFoundException: The Web application at http://xxx.xxx.com could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.
at Microsoft.SharePoint.SPSite..ctor(SPFarm farm, Uri requestUri, Boolean contextSite, SPUserToken userToken)
at Microsoft.SharePoint.SPSite..ctor(String requestUrl)

There’s a number of possible causes and it took going through some pain in order to resolve which route to take. The standard contingencies are explained quite well on http://www.thorntontechnical.com/tech/sharepoint/new-spsite-filenotfoundexception. None of those, possibly valid error causes, solved my beef.

In the end I found that we don’t actually need to be local with VS on the SharePoint server the solution is compiled against- it was just a matter of finding out how to reference the application context: the Nintex way. In this case, it was being handled by Nintex and the method used was not seemingly explained in the SDK or documented. Looking a bit deeper it became clear the application context was being fed in by Nintex.

Working from the DeployWorkflowActionWithFeature example in the Nintex Workflow 2010 SDK, we can see that in the EventLogAdapter.cs in the project, the context is initially set up in the following function:

public override CompositeActivity AddActivityToWorkflow(PublishContext context)
        {
            EventLogActivity activity = new EventLogActivity();

            Dictionary<string, ActivityParameterHelper> parameters = context.Config.GetParameterHelpers();

            parameters[Parameter_Message].AssignTo(activity, EventLogActivity.MessageProperty, context);
            parameters[Parameter_EventSource].AssignTo(activity, EventLogActivity.EventSourceProperty, context);

            activity.SetBinding(EventLogActivity.__ContextProperty, new ActivityBind(context.ParentWorkflow.Name, StandardWorkflowDataItems.__context));
            activity.SetBinding(EventLogActivity.__ListItemProperty, new ActivityBind(context.ParentWorkflow.Name, StandardWorkflowDataItems.__item));
            activity.SetBinding(EventLogActivity.__ListIdProperty, new ActivityBind(context.ParentWorkflow.Name, StandardWorkflowDataItems.__list));

            ActivityFlags f = new ActivityFlags();
            f.AddLabelsFromConfig(context);
            f.AssignTo(activity);

            context.ParentActivity.Activities.Add(activity);
            
            return null;
        }

That function sets up the __context for use in EventLogActivity.cs as follows:

public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(EventLogActivity));

Now that we have that rolling, we can use the __Context object with SPSite to get our current application URL.
SO, instead of using this:

SPSite site = new SPSite(“http://mysite/sitename”);

Use this:

SPSite site = new SPSite(this.__Context.Site.Url);

You now have the basis to perform all the wonderful SharePoint API stuff you need to do within the context of the Nintex Custom Action.

Get Check-in Comments with Nintex

NOTE: I’ve posted a revised version of this type of method for getting version history. The SQL in this post is not to be trusted! (but the rest is still good so I’ll leave the post as-is for posterity).

I needed to grab the document check-in comment insides of a Nintex 2010 / SharePoint 2010 list workflow. I couldn’t seem to locate the field anywhere Was told by Nintex support the following:

“It is not possible to reference the version history of a document within a workflow similar to how you can reference standard SharePoint fields. Even the web service method GetVersionCollection: http://msdn.microsoft.com/en-us/library/lists.lists.getversioncollection(v=office.12).aspx only returns the version history for a specific field. There may be another web service Microsoft exposes to enable this however this would be a question directly for MS.”

Oh well, right? Never say die! Use the Execute SQL Query widget in Nintex and let’s do some data mining:

1. Add an Execute SQL Query action to wherever in your Nintex workflow you need to access the Check-in comment.

2. Create a variable to store the check-in comment, in this case I call it vCheckInComment.

3. Add your SQL connection string. Considering that using Windows Authentication is probably what you’re going to be dealing with when using SharePoint, you will need the DB service account credentials.

4. Create your SQL query. For getting the check-in comments it is simple : In your SharePoint Content database there will be a table called AllDocs which contains two columns of interest: LeafName and CheckInComment.  You Can also grab the ListID GUID in there if needed – in this example I am already inside a Query List / For Each loop which has filtered the records based on the current list I am working with. The LeafName column stores the document e.g. MyDocument.doc. The CheckInComment column stores the comment for that file. In this example the {WorkflowVariable:vDocumentName} Nintex variable is my document name variable:

And that’s that – the check-in comment query associated with that documents record goes in the vCheckInComment column.

Disclaimer: there’s much more to the DB structure then just the document name and check-in comment. Versioning isn’t this simple. Also, running ad-hoc SQL queries on SharePoint is generally not best practice and you will get chewed out by MVP’s.  Reasons why ad-hoc SQL is bad news (see http://www.sharepoint4arabs.com/AymanElHattab/Lists/Posts/Post.aspx?ID=99 for a good summary)

  1. This is completely unsupported by the EULA you agreed to when you installed SharePoint.
  2. Your queries are not guaranteed to work after applying any patches or service packs to SharePoint since Microsoft could change the database schema anytime.
  3. Directly querying the database can place extra load on a server and hence performance issues.
  4. Direct SELECT statements against the database take shared read locks at the default transaction level so your custom queries might cause deadlocks and hence stability issues.
  5. Your custom queries might lead to incorrect data being retrieved.

Definitely run your SQL queries with NoLock on and keep it to simple, read-only queries if you’re going to pull stunts like running SQL queries from Nintex as described in this post. Also carefully consider versioning and data commit issues inherent from the SharePoint architecture side of things before counting on any of the results you pull out as gospel.