Tag Archives: Workflow

SharePoint 2013 List Workflows Failing

Quick Post.

Today I had an issue with a SharePoint 2013 List Workflow not running on a SharePoint Online Team Site.

 

Retrying last request. Next attempt scheduled in less than one minute. Details of last request: HTTP  to https://<SomeCoolTenant>.sharepoint.com/sites/<SomeCoolSite>/_api/web/lists(guid'**********************************') Correlation Id:  Instance Id: *************************************

System.Net.WebException: The request was aborted: The request was canceled. ---> System.InvalidOperationException: Failed to fetch an access token from the token service. The token service returned an error type of 'unauthorized_client' with the following description: AADSTS70001: Application with identifier '**************************' was not found in the directory **************************************
Trace ID: **********************************
Correlation ID: *****************************************
Timestamp: 2017-10-30 14:07:03Z ---> System.Net.WebException: The remote server returned an error: (400) Bad Request.
at System.Net.HttpWebRequest.GetResponse()
at Microsoft.Activities.Hosting.Security.OAuthS2SSecurityTokenServiceCredential.FetchAccessToken(Uri stsUri, String targetServiceAudience, String authenticatorToken, HttpWebRequest request, TimeSpan timeout, EventTraceActivity eventTraceActivity, TimeSpan& expirationDuration)
--- End of inner exception stack trace ---
at Microsoft.Activities.Hosting.Security.OAuthS2SSecurityTokenServiceCredential.FetchAccessToken(Uri stsUri, String targetServiceAudience, String authenticatorToken, HttpWebRequest request, TimeSpan timeout, EventTraceActivity eventTraceActivity, TimeSpan& expirationDuration)
at Microsoft.Activities.Hosting.Security.OAuthS2SSecurityTokenServiceCredential.GetAccessTokenFromTokenService(OAuthS2SPrincipal client, OAuthS2SPrincipal targetServiceAudience, HttpWebRequest originalRequest, EventTraceActivity eventTraceActivity, TimeSpan& expirationDuration)
at Microsoft.Activities.Hosting.Security.OAuthS2SSecurityTokenServiceCredential.GetAuthorization(OAuthS2SAuthenticationChallenge[] bearerChallenges, HttpWebRequest request, EventTraceActivity eventTraceActivity)
at Microsoft.Activities.Hosting.Security.OAuthS2SAuthenticationModule.AuthenticateInternal(String challenge, WebRequest request, OAuthS2SCredential credential, EventTraceActivity eventTraceActivity)
at Microsoft.Activities.Hosting.Security.OAuthS2SAuthenticationModule.Authenticate(String challenge, WebRequest request, ICredentials credentials)
at System.Net.AuthenticationManagerDefault.Authenticate(String challenge, WebRequest request, ICredentials credentials)
at System.Net.AuthenticationState.AttemptAuthenticate(HttpWebRequest httpWebRequest, ICredentials authInfo)
at System.Net.HttpWebRequest.CheckResubmitForAuth()
at System.Net.HttpWebRequest.CheckResubmit(Exception& e, Boolean& disableUpload)
at System.Net.HttpWebRequest.DoSubmitRequestProcessing(Exception& exception)
at System.Net.HttpWebRequest.ProcessResponse()
at System.Net.HttpWebRequest.SetResponse(CoreResponseData coreResponseData)
--- End of inner exception stack trace ---
at Microsoft.Workflow.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
at Microsoft.Activities.Hosting.HostedHttpExtension.HttpRequestWorkItem.HttpRequestWorkItemAsyncResult.End(IAsyncResult result, Int32& responseCode)
at Microsoft.Activities.Hosting.HostedHttpExtension.HttpRequestWorkItem.OnEndComplete(ScheduledWorkItemContext context, IAsyncResult result)

 

Turns out that I had forgotten to enable the Workflows can use app permissions site feature:

So – If you’re not yet using Microsoft Flow and still need those SharePoint 2013 Workflows, remember to enable this site feature.

InfoPath Notify on Specific Changed Fields

Scenario:

  • Notify specific users upon the change of any field in an infopath form excluding a limited number of fields.
  • InfoPath Full Trust Form
  • SharePoint designer Workflows

I’ve seen lots of people ask for this, with a lot of  the same general response:

it’s not really possible to maintain field-specific change history, or field-specific alerting

I think that Solution 2 below could address this.

Solution 1:

set up rules on every field in the form to set “NotifyParticipatns” to 1 on change.

Pros:

  • No code required

Cons:

  • Lots of rules and room for error

Solution 2:

Global event listener for all xml fields.  Note the XPath selector used for registering the Changed event handler:

"/my:myFields/*"

Conditional for which fields should be included / excluded from the alert.

Set the “NotifyParticipants” based on conditional result.


 public void InternalStartup()
 {
 EventManager.FormEvents.Loading += new LoadingEventHandler(FormEvents_Loading);
 EventManager.XmlEvents["/my:myFields/*"].Changed += new XmlChangedEventHandler(Form_Changed);
 }

<br data-mce-bogus="1">

public void Form_Changed(object sender, XmlEventArgs e)
 {
 // Write your code here to change the main data source.
 List&lt;string&gt; AlertableFields = new List&lt;string&gt;();
 string ModifiedField = e.Site.Name.ToString();
 AlertableFields.Add("my:Street");
 if( AlertableFields.Contains(ModifiedField))
 {
 Debug.WriteLine("Alerting on " + ModifiedField );
 }
 else{
 Debug.WriteLine("Not alerting on " + ModifiedField );
 }
 
 }

 

Pros:

  • Much cleaner solution

Cons:

  • Code.
  • Full Trust

 

Display Approval Tasks on InfoPath Form

I’be been working through building InfoPath forms to streamline the approval process of some internal documents, and one of the project requirements is to display the date / time as well as comments of each person who approves a document.

I built a SharePoint Designer workflow which first computes the approval routing (which varies between 8 and 10 approvers depending on the value of some fields),  then collects the approvals via the “Start Approval Process” task, and then emails up to 10 SharePoint groups based on a different set of criteria on each document.

SharePoint Designer Workflows store these “Assigned Tasks” in a Task List, which the developer is able to specify.  Each Task in the Task List contains a HIDDEN COLUMN called WorkflowItemId which associates the Task with the Item against which the workflow is running.   This column is a pesky little bugger for reasons explained below.

There is a blog post which describes one method for displaying all approvals tasks on the actual InfoPath form which goes roughly as follows:

  1. Create a new custom list containing all of the columns you need to reference
  2. Edit the “Behavior of a Single Task” for the Approval Process in question so that if the outcome is approved, add a new item to the custom list
  3. Add a Data Connection on the InfoPath form to pull data from the new custom list and display it on the form.

I didn’t want to go through the hassle of creating a separate list for each workflow I’m running, just to store data that’s already being stored in the associated Task List.

So, the big question: Why don’t you just add the Task List as an InfoPath Datasource and call it a day?

Well, the answer to that question may infuriate you: you are unable to filter the list according to the ID of the item in question because the attribute that stores the item id (WorkflowItemId) is forcibly hidden! 

  • InfoPath does not provide WorkflowItemId as an option in the Data Connection query path.
  • CSOM CAML queries error out when you attempt to use WorkflowItemId as a query field, so the SOAP / REST Data Connections in InfoPath also fail.

Other than the solution above, there are really only two other options:

I went the second route, and created such a web service, which is available here: https://github.com/bciu22/ApprovalTaskListService.

The result is that you can add an InfoPath Data Connection that looks something like this:

So that you can have a repeating table on your form with all approvals that looks something like this:

 

Collecting User Data in SharePoint 2010 with custom Site Columns

The Task: Build a system to archive paper documents (being scanned from e-mail enabled scanners) and optimize for retrieval

I decided to build an E-Mail enabled library to get the documents into SharePoint.   This allows users to save the email address in their contact list on the copier, and makes scanning in documents very easy.

To gather the metadata for these documents, I used the “Collect  Data From a User” (CUD) Action in SharePoint Designer.  This created a Content Type based on the name of the task – In my case “Student Document Data Collection.”

I then added some of my existing site columns to this content type from SPD – things like first name, last name, and district.  I didn’t want to use the CUD wizard to add these fields to the data collection task because a) all of the fields already exist in the site, and b) some of the fields are multiple choice, and I really don’t want to manage two instances of the same data!

After I modified the content type, I refreshed the workflow and returned to the CUD wizard in SPD, and saw that all of my fields populated! Hoorah!

I proceeded to build the rest of the workflow, referencing the fields collected in the CUD task in the normal manner; however, I was noticing a problem: None of the user entered data was showing up!

How could this be? SharePoint was prompting me for the data, I entered it, and I hit save… It should be there, right?  I wrote entries to the workflow history log to see if maybe the data just wasn’t being applied to the current item.  No dice – It looked like SharePoint just wasn’t storing the collected data.

Thanks to reddit user sbrick89, It looks like fields (Site Columns) created in the CUD action within SPD actually have a distinction from standard Site Columns! It’s not a big difference, but it will mess up your day (or, in my case WEEK)!   These fields are prefixed with “FieldName_”.

I jumped into my SharePoint Management PowerShell and whipped this up in order to create my Site Columns (in a way that they will be usable for data collection):

$SiteURL = “<YOUR SITE HERE>”

$Web = Get-SPWeb $SiteURL
$FieldXMLString = ‘<Field Type=”Text”
Name=”FieldName_StudentFirstName”
Description=”Student First Name”
DisplayName=”Student First Name”
Group=”0 Student Columns”
Hidden=”FALSE”
Required=”FALSE”
Sealed=”FALSE”
ShowInDisplayForm=”TRUE”
ShowInEditForm=”TRUE”
ShowInListSettings=”TRUE”
ShowInNewForm=”TRUE”></Field>’
$Web.Fields.AddFieldAsXML($fieldXMLString)

Documentation for the syntax of the $FieldXMLString can be found here: https://msdn.microsoft.com/en-us/library/office/ms437580(v=office.15).aspx

Of note is this “Name: Required Text: The name of a field. This is the internal name of a field and is guaranteed never to change for the lifetime of the field definition. It must be unique with respect to the set of fields in a list. The name is autogenerated based on the user-defined name for a field.

I also wanted to create a multiple choice Site Column for District:

$FieldXMLString = ‘<Field Type=”Choice”
Name=”FieldName_District”
Description=”District”
DisplayName=”District”
Group=”0 Student Columns”
Hidden=”FALSE”
Required=”FALSE”
Sealed=”FALSE”
ShowInDisplayForm=”TRUE”
ShowInEditForm=”TRUE”
ShowInListSettings=”TRUE”
ShowInNewForm=”TRUE”>
<CHOICES>
<Choice>District 1</Choice>
<Choice>District 2</Choice>
</CHOICES>
</Field>’
$Web.Fields.AddFieldAsXML($fieldXMLString)

After creating the Site Columns with the proper internal name, I was able to add the newly created site column to the CUD Content Type, update my workflow, and collect the user data successfully!   Yes, It does seem that any alterations (including changes to the items in a choice Site Colume) to the CUD Content Type require that the workflow be loaded in SPD, the CUD Step opened, “next through” the wizard, and the workflow re-published in order for the changes to appear in the actual data collection step.

Links:

http://www.sbrickey.com/Tech/Blog/Post/Secrets_Revealed-_SharePoint_Designer_-_Workflows_-_Approval_Task_-_Task_Form_Fields