Friday, November 15, 2013

SharePoint 2010 State Machine Workflow error: "Failed to Start Workflow"

I've been working on a custom state machine workflow for a specific content type. I've associated the workflow to the content type like this:

<AssociationCategories>ContentType;0x01........</AssociationCategories>

This workflow has a custom initiation form, in which I'm passing some options to the workflow.

After doing the association to the content type I started getting the following error: "Failed to Start Workflow"

After doing a bit of debugging and head scratching I found that in the StartListWorkflow() method inside the initiation page in which the workflow association is retrieved from the workflowList.WorkflowAssociations list and it does not take into consideration the ContentType workflow associations.

private void StartListWorkflow()
{
 SPWorkflowAssociation association = this.workflowList.WorkflowAssociations[new Guid(this.associationGuid)];
 
        this.Web.Site.WorkflowManager.StartWorkflow(workflowListItem, association, GetInitiationData());
 SPUtility.Redirect(this.workflowList.DefaultViewUrl, SPRedirectFlags.UseSource, HttpContext.Current);
}

So I replaced this line:

SPWorkflowAssociation association = this.workflowList.WorkflowAssociations[new Guid(this.associationGuid)];

with this line:

SPWorkflowAssociation association = this.workflowList.ContentTypes[workflowListItem.ContentTypeId].WorkflowAssociations[new Guid(this.associationGuid)];

in which I'm getting looking for the association in the WorkflowAssociations of the list content type of the workflowListItem.

Thursday, October 10, 2013

SharePoint 2010 - Enable and configure unique Document IDs

There is a great article on how to Enable and configure unique Document IDs on Microsoft.com.

In short you need to:

  • Activate the Document ID site collection feature
  • Enable and configure the use of Document IDs in a site collection

But what it doesn't mention is that behind the scenes there are two time jobs that need to run to activate this feature: one to add the Document ID column and one to generate unique ids for the existing documents. But, these jobs are set to run once a day.

So if you need your unique Document IDs to be activate right away, you need to go to Central Administration and run these two timer jobs for your respective web application:

  • Document ID enable/disable job 
  • Document ID assignment job 


Thursday, September 19, 2013

System.InvalidOperationException: The event receiver context for Workflow is invalid.

Ever got this error while developing SharePoint 2010 Workflows in Visual Studio?

System.InvalidOperationException: The event receiver context for Workflow is invalid.
at Microsoft.SharePoint.SPEventReceiverDefinition.ValidContext()
at Microsoft.SharePoint.SPEventReceiverDefinition.GetSqlCommandToAddEventReceivers(IList`1 erds)
at Microsoft.SharePoint.Workflow.SPWinOESubscriptionService.CommitNewSubscriptions(Transaction txn, IList`1 erds)


Check the you have set the all the TaskIds in your code:

TaskId = Guid.NewGuid();

If this is not the case need to check that your Correlation Tokens are setup correctly.

Tuesday, July 30, 2013

SPDisposeCheck for Visual Studio 2012

Found a great project on CodePlex that allows the creation of an SPDisposeCheck Static Code Analysis Ruleset: http://spdisposecheck2012.codeplex.com 

You also have a small video to see how is setup: http://youtu.be/OwiKKYAlXDc

Thursday, April 4, 2013

PowerShell script to add work email to the list fields for the author

The Author (Created By) field is actually an lookup field to the hidden User Information list.

If you need to add the work email of the Author (Created By field) user to a specific list it can be done by adding a dependent lookup field for the Author field:
$site = get-spsite "site url here";
$list = $site.RootWeb.Lists["list name"];

$createdByEmailGuid = $web.Fields.AddDependentLookup("Work e-mail", [Microsoft.SharePoint.SPBuiltInFieldId]::Author);
$createdByEmail = $web.Fields.GetFieldByInternalName($createdByEmailGuid);
$createdByEmail.Description = "Work e-mail address of the Author.";
$createdByEmail.LookupField = $web.Fields[[Microsoft.SharePoint.SPBuiltInFieldId]::EMail].InternalName;
$createdByEmail.Update();
$web.Update();

$list.Fields.Add($createdByEmail);
$list.Update();
If additional fields are needed the same method can be applied. Here is a list of fields that can be added from the User Information list:

- Work e-mail
- Mobile phone
- About me
- Picture
- Department
- Title
- SIP Address
- First name
- Last name
- Work phone
- User name
- Web site
- Ask Me About
- Office


SharePoint 2010 retrieving lookup values using ECMAScript

Script to retrieve single and multiple value lookup fields values using SharePoint 2010 Client Object Model for JavaScript (ECMAScript):


var listName = "list name here";
var listItemId = 23; // id here

function retrieveLookupValues() {
    var clientContext = new SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getByTitle(listName);
    var selectedItems = SP.ListOperation.Selection.getSelectedItems();
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml("< View >< Query >< Where >< Eq >< FieldRef Name='ID' / >< Value Type='Counter'>" + listItemId + "< /Value>< /Eq>< /Where>< /Query>< RowLimit>100< /RowLimit>< /View>");
    this.collListItem = oList.getItems(camlQuery);
    clientContext.load(collListItem, 'Include(CustomSingelLookupFld, CustomMultilLookupFld)');
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded(sender, args) {
 var listInfo = "";
    var listItemEnumerator = collListItem.getEnumerator();

    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
        // get single value LookupField:
        var oCustomSingelLookupFld = oListItem.get_item("CustomSingelLookupFld");
  listInfo += "oCustomSingelLookupFld.Value = " + oCustomSingelLookupFld.get_lookupValue() + " \t oCustomSingelLookupFld.Id = " + oCustomSingelLookupFld.get_lookupId();
  // get multiple value LookupField:
        var oCustomMultilLookupFld = oListItem.get_item("CustomMultilLookupFld");
  for(var ix = 0; ix < oCustomMultilLookupFld.length; ix++){
   listInfo += "oCustomSingelLookupFld[" + ix + "].Value = " + oCustomMultilLookupFld[ix].get_lookupValue() + " \t oCustomSingelLookupFld[" + ix + "].Id = " + oCustomMultilLookupFld[ix].get_lookupId();
  }
    }
 alert(listInfo);
}

function onQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message());
}

Monday, February 4, 2013

Creating SharePoint 2010 Calculated Field from code in sites with different regional settings

Say you need to create the following calculated column in different sites that have different regional settings: English, French, etc. to format the DateTime [Start Time] filed to "dd-mm-yyyy".

The following formula would look list this in English - with a comma separator:
=TEXT([Start Time],"dd-mm-yyyy")
Like this in french - with a semicolon separator:
=TEXT([Start Time];"dd-mm-yyyy")
When creating the column from from code  behind to treat this  the SPWeb.Locale.TextInfo.ListSeparator property must be used to get the correct list separator:
SPList spList = SPContext.Current.Web.Lists["List Title"];
string newFieldName = spList.Add("CalculatedField", SPFieldType.Calculated, false);
SPFieldCalculated newField = (SPFieldCalculated)spList.GetField(newFieldName);
newField.Formula = String.Format(@"=TEXT([Start Time]{0} ""dd-mm-yyyy"")", SPContext.Current.Web.Locale.TextInfo.ListSeparator);
newField.Update();