Tuesday, January 08, 2008

Cross Updating Windows Workflow Tasks in Parallel Activity

Parallel activities in Windows Workflow are independent as the name suggests. How could we then update Task A from Task B when Task A and Task B are running in parallel? After spending 1 hour, I figured it out.

1) Use "Update Task" shape for updating Task A and drop it in the "parallel" arm of Task B. The position of this task could be above the "Complete Task" or as required. But it should be under the "create task" shape for Task B.

2) Here is the imporant part. Set the correlation token as the correlation token used for Task A even though this task is under Task B related tasks. This correlation token will direct the update task to the correct task (Task A in our case)

3) Bind the TaskID to existing Task ID for Task A.

3) Use syntax "TaskProperties.ExtendedProperties["NameOfInfopathField_inTaskA_thatis_to_be_updated"]="desiredvalue"

Important:

Parallel workflows in WF are actually processed in a sequence. Left branch is processed first and then control moves towards the right . While cross updating tasks, correlation ID is the key that ties the different tasks together. For tasks on the extreme right arm, all the correlation IDs in the workflow are available. But this selection reduces are we move towards left. In order to update a task on the right side of a given task, the correlation ID will not be available from the work flow design view. But going to deign code file(*.designer.cs / *.designer.vb) gives the flexibility to link the correlation ID with the task that is to be updated.

i.e.

this.UpdateFromTaskOnLeftSide =CorrelationToken (this will be token for the task on the right side that is being updated from left side).

Monday, January 07, 2008

Accessing SQL data from Infopath Form Control

A control in infopath form can be configured to receive data from XML, WebService, SharePoint List and SQL database (only). In this article I will focus on using SQL database as secondary datasource. I used SQL database to hold values for login in one column and second column gave the user groups for that LogIn. I used these Groups to control the views that a user can access. For Example: You could add rule to restrict an IT user to view data for IT only and not for Finance or Marketing.



This is what you do:


1) Create a table and name it "RulesGroup". Add two columns : UserLogIn and UserGroup




2) In the infopath form create two text box control: UserName and UserGroup

3) Create a secondary datasource and configure it to receive data from SQL database. Use the wizard to point to the correct table.

4) In the infopath form: Use infopath function username() to populate UserName text box.
Map the UserGroup text box with following Xpath:

xdXDocument:GetDOM("RolesGroup")/dfs:myFields/dfs:dataFields/d:RolesGroup[@UserLogIn = "shashi"]/@UserGroup

PS: XML generated by the wizard marks the 2 user defined columns as "attributes". So there is need to user @ in Xpath expression.

In our case if UserName is "shashi" the UserGroup will be "Operations".

New users and Groups can be added in DB as required and accordingly Infopath Views can be programmed based on Groups.

Remember: While using form services to host infopath form, additional requirement will be creating a new Univeral Data Connection(UDC) file in Data Connection Library under the site collection. This UDC file maps the connection details between infopath form and SQL service. SQL server can't really authenticate the user name being passed directly from the infopath form. The user name comes as "" (blank). One way of getting around is to use proxy user name and password in case the user name is blank. But this will compromise security in Big Way. Use of UDC file helps in this regard. Also, it allows you set up custom User Groups based on User Names. These user groups can be then used to limit access to certain views as explained before in this article.