Category Archives: SharePoint Workflow

Create Sites (SPWeb) via SharePoint Designer Workflow

This blog entry is more of an "in the realm of the possible" entry vs. concrete info.

We have a technical design that calls for us to create a site in a site collection via a manually launched workflow process.  Basically, users enter data into a "new customer" custom list and then when they have finished and validated the data entry process, we need to create a site for that customer.

I’m both a big fan of declarative workflow as well as a weak visual studio workflow programmer, so I wanted to meet the requirement using SharePoint Designer.

I plan to write about this in greater detail (and hopefully present to a user group or two in the coming year), but here’s the overall solution:

  • Create a custom action that integrates with SPD.
  • The custom action allows SPD to invoke a web service and pass it a string of XML.
  • Web service locates the row in the custom list and creates a new site as per the data for that new client using a custom site definition.
  • Web service then updates the custom list with some information such as a link to the new site.

We considered other approaches, such as event handlers and visual studio based workflow.  The SPD approach gives our end users a little more control over the process.  Granted, there’s a lot of C# code in this solution, but it’s wrapped inside a declarative workflow, so we get some of the benefits of declarative workflow while hooking into the site-creation service.

All we need now is an easy tool to automatically migrate SPD workflows around as easily as we can for visual studio workflows and we’ll really be cooking with gas 🙂  I understand that some folk are out there working on this problem and I hope they have some good success with it soon.

</end>

 Subscribe to my blog.

Technorati Tags: ,

Integrate SharePoint Designer Workflows with Web Services

I’ve been playing around with custom actions for SharePoint Designer for some time (see here for some detailed stuff, if that interests you).

In my current project, we need to do some fairly heavy lifting and we want to use declarative SPD workflow to manage the associated business process. 

Long story short, this is entirely possible.  I extended my Codeplex project to invoke a "helper service" and now we can invoke a web service directly from an SPD workflow. 

Here’s the signature:

 public string Dispatcher(
        Guid WebID, // Passed by the runtime environment
        Guid SiteID, // Passed by the runtime environment
        string ListID, // Passed by the RTE (don't know why this is a string, not a GUID)
        int ListItemID, // Passed by the RTE.
        string XmlMessage) // Passed by the user as declared in SPD.

This leverages the fact that we can get at important workflow information, like the site, list ID, etc.  This is well documented in several places for those of you interested in creating your own custom actions.  The idea is to extract the XML string as provided by the user to dispatch an appropriate procedure.  Fun stuff!

Sadly, this is obviously a one-way ticket down to "Loosey Goosey" anti-pattern land, but it’s better than hitting a brick wall 🙂

Is it an anti-pattern if you do it even though you know it’s an anti-pattern?

I hope to wrap this inside Codeplex in the near future.  If you’re interested in me doing so, give me poke (email or leave a comment) and I’ll be that more enthusiastic about doing it 🙂

</end>

 Subscribe to my blog.

Technorati Tags: ,

SPD Workflow “Collect Data From A User”: Modify the Generated Task Form

I’m working on a project that uses five different SharePoint Designer work flows to handle some document approvals.  SPD provides the "collect data from a user" action so that we can prompt the user for different bits of information, such as whether they approve it, some comments and maybe ask what they had for dinner the other night.

The forms are perfectly functional.  They are tied to a task list as a content type.  They are 100% system-generated.  This is their strength and weakness.  If we can live with the default form, then we’re good to go.  However, we don’t have too much control over how SPD creates the form.  If we don’t like that default behavior, we need to resort to various tricks to get around it (for example, setting priority on a task). 

I needed to provide a link on these task forms that opened up the view properties (dispform.asxp) of the "related item" in a new window.  This provides one-click access to the meta data of the related item.  This is what I mean:

image

Thankfully, we can do that and it’s not very hard.  Broadly speaking, fire up SPD, navigate to the directory that houses the workflow files and open the ASPX file you want to modify.  These are just classic XSL transform instructions and if you’ve mucked about with itemstyle.xsl, search or other XSL scenarios, this will be easy for you.  In fact, I found it to be generally easier since the generated form is somewhat easier to follow as compared to a search core results web part (or the nightmarish CWQP).

Of course, there is one major pitfall.  SPD’s workflow editor expects full control over that file.  If you modify it, SPD will happily overwrite your changes give the right set of circumstances.  I did two quick tests to see how bad this could get.  They both presuppose that you’ve crafted a valid SPD workflow that uses the "collect data from a user" step.

Test 1:

  • Modify the ASPX file by hand.
  • Test it (verify that your changes were properly saved and didn’t break anything).
  • Open up the workflow and add an unrelated action (such as "log to history").
  • Save the workflow.

Result: In this case, SPD did not re-create the form.

Test 2:

  • Do the same as #1 except directly modify the "collect data from a user" action.

Result: This re-creates the form from scratch, over-writing your changes.

Final Notes:

  • At least two SPD actions create forms like this: "Collect Data From a User" and "Assign To Do Item".  Both of these actions’ forms can be manually modified.
  • I was able to generate my link to dispform.aspx because, in this case, the relate item always has its ID embedded in the related item’s URL.  I was able to extract it and then build an <a href> based on it to provide the one-click meta data access feature.  It’s unlikely that your URL follows this rule.  There may be other ways to get the ID of the related item but I have not had to cross that bridge, so I don’t know if gets to the other side of the chasm.
  • I didn’t investigate, but I would not be surprised if there is some kind of template file in the 12 hive that I could modify to affect how SPD generates the default forms (much like we can modify alert templates).

</end>

Subscribe to my blog!

Technorati Tags: ,

Solution (sort of): Set Priority on a Task Using SharePoint Designer

I have a business scenario like this:

  • A user uploads a document to a document library.
  • She selects a content type and enters meta data as needed. One of the meta data fields is a flag, "Urgent".
  • This triggers a SharePoint Designer workflow that, among other things, uses the "Collect Data from a User" action.

"Collect Data from a User" creates an item in a task list requesting approval for that document.

I needed to create a view of the task list that showed urgent requests for approval.

Solution: Put the word "URGENT:" into the title of these tasks. 

I would have preferred to specify the priority field directly.  However, I was unable to do that for several reasons:

  1. The collect data action does not provide a mechanism to update any field other than title (and those additional fields for which you want to collect data).
  2. The "assign a to do item" action has the same problem.
  3. It’s possible to insert an item into a list (i.e. insert an item into the task list directly) but this not a blocking action.  That means that the workflow will not wait for the user to complete that task.

I considered a few approaches before (thankfully) realizing we could just put "urgent" in the title.

  1. Start a workflow on the task list itself so that when a new task is created, it somehow cross references back to the document that started the first workflow, pull out the urgent flag value and update priority as needed. 
  2. Do something similar with an event receiver.  On create of the task, locate the associated document and update priority as needed.
  3. Use the "create list item" action in conjunction with the "wait for field change" action and an event receiver.  If we create a list item, we can specify all the fields we want.  Use an event receiver to update the original item when the user completes the task and the "wait for field change" action’s condition would be met and the workflow would proceed.  (For some reason, I had more or less settled on this approach before wisely deciding to walk away for a while).

There is a drawback to my solution (aside from the obvious fact that only the text of the title indicates urgency).  Since "collect feedback" only accepts hard coded title names, I need to use two different collect feedback actions whose only difference is that hard coded title. 

But, at least there’s a solution that does not require event receivers or custom SPD actions.

If someone has solved this in a more clever way, please let me know.

</end>

Quick and Easy: Automatically Open InfoPath Form From SharePoint Designer Email

UPDATE: Madjur Ahuja points out this link from a newsgroup discussion: http://msdn2.microsoft.com/en-us/library/ms772417.aspx.  It’s pretty definitive.

===

We often want to embed hyperlinks to InfoPath forms in emails sent from SharePoint Designer workflows.  When users receive these emails, they can click on the link from the email and go directly to the InfoPath form.

This monster URL construction works for me:

http://server/sites/departments/Technical%20Services/InformationTechnology/HelpDesk/_layouts/FormServer.aspx?XmlLocation=/sites/departments/Technical%20Services/InformationTechnology/HelpDesk/REC%20REM%20RED%20Forms/REC2007-12-18T11_33_48.xml&Source=http%3A%2F%2Fserver%2Ecorp%2Edomain%2Ecom%2Fsites%2Fdepartments%2FTechnical%2520Services%2FInformationTechnology%2FHelpDesk%2FREC%2520REM%2520RED%2520Forms%2FForms%2FAllItems%2Easpx&DefaultItemOpen=1

 

Replace the bolded red text with the name of the form, as shown in the following screenshot:

image

Note that there is a lot of hard-coded path in that URL, as well as a URL-encoded component.  If this is too hard to translate to your specific situation, try turning on alerts for the form library.  Post a form and when you get the email, view the source of the email and you’ll see everything you need to include.

Astute readers may notice that the above email body also shows a link that directly accesses the task via a filtered view.  I plan to explain that in greater detail in a future post. 

</end>

Technorati Tags:

MOSS Tells Me “Access Denied” to Edit a Workflow Task, But I Really Do Have Access

I’ve implemented a workflow using SharePoint Designer in a site which is mainly read-only to "NT_AUTHORITY\Authenticated Users" (i.e. everyone).  There is a forms library for an InfoPath form.  There is an associated workflow tasks list as well so that when the workflow operates, it can assign tasks to people.

I break permission for the forms library and task list so that any authenticated user can create forms and update their assigned tasks.

I test with my low-privileges test account. 

Can I fill out and save a form to the library? –> YES

Can I access the task from an email link? –> YES

Can I see an Edit workflow task link –> YES

Can I click on that link?  –> NO … Permission Denied.

Why can I see an edit link that denies me permission when I click on it?  That’s not how it’s supposed to work…

I go through the security configuration again, very closely.  I do it again.  I consider deleting this post because I obviously don’t know anything about security.

Finally, I search the Internets.  I find this highly unlikely MSDN forum thread:  http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=1838253&SiteID=17

The posters appear to be suggesting that the simple act of exporting the workflow to a drive platter will fix a MOSS security issue?  I can hardly believe I just typed that.  I’m reminded of the South Park episode about the 9/11 conspiracy where Stan is asking our Preznit, "Really?" over and over again. 

So, nothing to lose, I fire up SPD, right-click on the workflow and save it to my c:\ drive.  That would be the c:\ drive on my laptop.  I’m looking over my shoulder the whole time so that no one will ask me, "why are you saving that workflow to your laptop?"

Incredibly, that solves my problem.  I can edit the task.

I hereby nominate this to be the Most Bizarre Workflow Workaround of 2007.

</end>

Technorati Tags:

SharePoint Designer, Current Item’s “Encoded Absolute URL” and HTTPS

We often want to send an email that includes a hyperlink to the item or document that triggered the workflow.  We can use current item’s "Encoded Absolute URL" for this purpose.  However, it always seems to use "http" for the URL protocol.  If your site runs on HTTPS then it will not work for you.

image

As far as I know, there is no out of the box solution to this problem.  If you need to use HTTPS, you have no out of the box option.

To solve it, create a custom action that provides a string replace function to use in your workflow.  Alternatively, use a 3rd party tool such as the excellent package here: http://www.codeplex.com/spdwfextensions 🙂

</end>

Technorati Tags: ,

SharePoint Designer Email Sends ???? in an Email

Forum users occasionally ask: Why does SharePoint Designer put ???? into my email instead of a field value?

One reason this happens is because the variable to which you refer is null.

This can happen because you are trying to reference a field from the "current item" but the user never entered a value into that form field.

<end/>

Technorati Tags:

Compare / Test for Blank Dates in SharePoint Designer Workflow

Scenario: In a SharePoint Designer workflow, you need to determine if a date field is blank.  

Problem: SPD does not provide a direct method for comparing dates to anything other than a date.  You cannot create a condition like this: "If [DateField] equals blank".

Solution: Convert the date to a string.  Use string comparison to determine if the date is blank. 

Screen Shots:

The following screen shots show how to do this.  In this scenario, a field on an item, "Environmental Permits:First Permit Reminder Date", is submitted and the workflow fires in response.

image

 

 image

Notes:

When I tried this, I was pleasantly surprised to learn that it works.  I was worried that SharePoint Designer might disallow the string assignment (Variable:StringReminderDateDate) but it did allow it.

I was also concerned that allowing it, the value might be null and either blow up the WF at runtime or maybe raise the global temperature 1/2 a degree, but those concerns were unfounded.

</end>

Technorati Tags:

SharePoint Designer Workflow Custom Action — Observation About <FieldBind Designer Type=”StringBuilder” … />

Just a quick observation that there’s a very important difference between these two definitions:

<FieldBind Field="InParam1" DesignerType="StringBuilder" Id="2" Text="Input parameter #1"/>

versus:

<FieldBind Field="InParam1" Id="2" Text="Input parameter #1"/>

The first shows like this in SPD:

image

while the latter shows like this:

image

I’m not sure how helpful these screen shots are but I put in the effort to make them so you have to view them 🙂

The observation is this: StringBuilder allows you to build a string (obviously) by mixing together string literals and workflow data (via the "Add Lookup" button in the lower left-hand corner).  When you use the Add Lookup button, it inserts a token in the form "[%token%]".  When SharePoint invokes your custom action, (C# code in my case), SharePoint passes the token itself, not the value of the token.  If you use the default designer type (the second type), SharePoint expands the token and passes actual value of the token to your action.

StringBuilder = BAD, default designer type = GOOD.

Of course, that’s not what I really mean.  Just don’t try and pass a parameter to your custom action when the designer type = StringBuilder.  Use the default  designer type and chain a StringBuilder to it up front if you need to build complex strings in your workflow (which incidentally is exactly what one does to create a dynamic subject for the email action, but that’s a subject for another blog entry, har har).

<end/>