Tuesday, February 10, 2009

Generate AccountName in ILM 2 custom workflow activity

I saw a question on the ILM 2 Connect site, and thought it would be a good candidate for a blog. I've been working with my esteemed colleagues Brad Turner and David Lundell on some ILM 2 engagements, and they do a fantastic job at leading by example.

Here I will show you how to create a custom workflow activity for ILM 2 in which you can generate an account name from the first/last name and update the target resource. Keep in mind that this blog entry is written in the context of the ILM "2" Release Candidate. For RTM, you should be able to do this with the function evaluator.

For simplicity, let's start with the Ensynch diagnostic activity. This handy little project contains an existing deployment-ready custom workflow activity that you can drop into any ILM 2 workflow.

Open the project in Visual Studio and double-click the EnsynchDiagnosticActivity.cs file. Drag a CodeActivity and an UpdateResourceActivity onto the design surface. Your design surface should now look like this:





In the properties window of the CodeActivity, bind the ExecuteCode property to a new method named "generateAccountName". This is where we'll write all of our custom code to generate the account name and submit it for update on the target object.

In the properties window of the UpdateResourceActivity, bind the ResourceId property to a new field named "TargetId", and bind the UpdateParameters to a new field named "MyUpdateParameters". Please use caution when binding these properties, and if you're unsure of what you're doing, you can follow these instructions to avoid a potential pitfall.

Note that the Ensynch diagnostic activity already contains a CurrentRequestActivity, which reads the current Request object. We'll use that to get the Target ID, and assign that to the TargetId field. Then, we'll submit the account name by adding it to the UpdateParameters collection.

Open the EnsynchDiagnosticActivity in the code editor and edit the generateAccountName method. We'll use a simple method for generating the account name, by combining the first and last name that we read from the Request parameters. In the interest of brevity, we'll forgo error checking on the account name. Note that we are using the built-in Request method to parse the Request parameters.


//--- Generate the account name from the Request parameters.
string accountName = "";
// Get the request parameters from the Request object.
ReadOnlyCollection<CreateRequestParameter> requestParameters =
this.currentRequest.ParseParameters<CreateRequestParameter>();
foreach (CreateRequestParameter requestParameter in requestParameters)
{
// Simply combine the first, last names to generate the account name.
if (requestParameter.PropertyName == "FirstName")
{
accountName = requestParameter.Value.ToString() + accountName;
}
else if (requestParameter.PropertyName == "LastName")
{
accountName = accountName + requestParameter.Value.ToString();
}
}

Now we'll grab the Target GUID from the currentRequest object and assign that to the field that we bound to the UpdateResourceActivity. We're essentially telling the UpdateResource to update the Target object, but note that we could just as easily update other objects (if the requestor has permission, of course).


//--- Tell the UpdateResourceActivity to update the Target object.
TargetId = currentRequest.Target.GetGuid();

Finally, we'll tell the UpdateResourceActivity to update the AccountName on the Target by adding the attribute to the UpdateParameters collection.


//--- Add the account name to the update parameters.
MyUpdateParameters = new UpdateRequestParameter[]
{
new UpdateRequestParameter("AccountName",
UpdateMode.Modify, accountName)
};

That's it for the generateAccountName method. One more thing we have to do for a successful build/deployment is to remove the initialization of the bound fields at the class level. Not sure where the problem lies, but this seems to fix it:


public Guid TargetId;
public UpdateRequestParameter[] MyUpdateParameters;

Now you have yourself a bona fide account name generator. You can follow the Ensynch walkthrough to learn how to deploy and test the activity. One final note: we haven't given any thought to ensuring uniqueness in this exercise. You have been warned!

Enjoy!

8 comments:

  1. Good post!
    Pingback from http://www.ilmbestpractices.com/blog/2009/02/another-talented-ensynchian-joins.html

    ReplyDelete
  2. Hey Joe! We meet in January at the ILM2 Partner Training event in Redmond. Best of luck with blog, it looks to be some very useful content!

    Keith Crosby

    ReplyDelete
  3. Hi Keith! Hi David!
    Thanks for the comments. Let me know if you find any leads for blog topics.
    Thanks!
    Joe

    ReplyDelete
  4. Joe,

    can you tell me what I'm doing wrong with this line:

    ReadOnlyCollection requestParameters = this.currentRequest.ParseParameters();

    VS2008 tells me I need a type argument for ReadOnlyCollection.

    Thanks,
    Carol

    ReplyDelete
  5. Hi Carol,

    Thanks for the heads-up. I had a problem with HTML encoding on my blog. Here's the fix:

    ReadOnlyCollection<CreateRequestParameter> requestParameters =
    this.currentRequest.ParseParameters<CreateRequestParameter>();


    Sorry about that!
    Joe

    ReplyDelete
  6. Hi Joe and thanks for a great post!
    I'm working for a customer with ILM2 and of course have the problem you address here but I had to take a bit further in order to get unique names in some cases.

    http://blog.softconstruction.se/post/2009/03/ILM2-Unique-Name-Workflow-Activity.aspx

    ReplyDelete
  7. Joe, Henrik:
    Great content in both your blogs on ILM "2" Workflow Activity.

    ReplyDelete
  8. Hi Joe I am doing an update on a field but after update it is again excuting the code..can you help me on this

    ReplyDelete