XPathFilter is null while generating UniqueAccountName
Hi, I am trying to generate unique AccountName via WF and having issues in EnumeratedResourceActivity. Eventhough I set up XPathFilter property the error message says the filter is empty(or not set). Here is the visual of my WF. So when a user is created with email let's say xyz@google.com I am trying to add AccountName to the user request here. If the user name is already present in portal I am appending 1 then 2 then 3 and so on. here is my logic public const string WF_ACTOR_GUID = "3f862651-ebee-4cf8-a824-0c9663757aCC"; public int loopCounter = 1; public bool loopAgain = true; public string _accountName; public string _email; public AddUniqueAccountName() { InitializeComponent(); } public string AccountName { get { return _accountName; } set { _accountName = value; } } public string Email { get { return _email; } set { _email = value; } } private void InitializeReadResource_ExecuteCode(object sender, EventArgs e) { this.readResourceActivity1.ActorId = new System.Guid(WF_ACTOR_GUID); this.readResourceActivity1.ResourceId = this.CurrentRequestActivity1_CurrentRequest1.Target.GetGuid(); } private void GenerateUniqueAccountName_ExecuteCode(object sender, EventArgs e) { this.readResourceActivity1.SelectionAttributes = new string[] { "AccountName", "Email" }; ResourceType user = readResourceActivity1.Resource; this.Email = (string)user["Email"]; this.AccountName = getAccountName(); } private void InitializeEnumerateResource_ExecuteCode(object sender, EventArgs e) { this.enumerateResourcesActivity1.ActorId = new System.Guid(WF_ACTOR_GUID); String resourceType = this.readResourceActivity1_Resource1["ObjectType"].ToString(); this.enumerateResourcesActivity1.Selection = new string[] { "AccountName" }; this.enumerateResourcesActivity1.XPathFilter = "/" + resourceType + "[AccountName =\'" + this.AccountName + "\']"; // /Person[AccountName='patelb'] } private void CheckUniqueness_ExecuteCode(object sender, EventArgs e) { int totalcount = this.enumerateResourcesActivity1.TotalResultsCount; ResourceType results = EnumerateResourcesActivity.GetCurrentIterationItem((CodeActivity)sender) as ResourceType; if (totalcount > 0) { this.AccountName = this.AccountName + loopCounter.ToString(); this.loopAgain = true; } else this.loopAgain = false; } private void InitializeUpdateTarget_ExecuteCode(object sender, EventArgs e) { this.UpdateResourceActivity1.UpdateParameters = new UpdateRequestParameter[1]; this.UpdateResourceActivity1.UpdateParameters[0] = new UpdateRequestParameter("AccountName", UpdateMode.Modify, this.AccountName); this.UpdateResourceActivity1.ActorId = new System.Guid(WF_ACTOR_GUID); this.UpdateResourceActivity1.ResourceId = this.CurrentRequestActivity1_CurrentRequest1.Target.GetGuid(); //new System.Guid("3b072ae5-8e8d-423c-ae85-af5d33869f94"); // } private void ThrowError_ExecuteCode(object sender, EventArgs e) { throw new WorkflowTerminatedException("No unique value found"); } Here is deginer code... public partial class AddUniqueAccountName { #region Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> [System.Diagnostics.DebuggerNonUserCode] [System.CodeDom.Compiler.GeneratedCode("", "")] private void InitializeComponent() { this.CanModifyActivities = true; System.Workflow.Activities.Rules.RuleConditionReference ruleconditionreference1 = new System.Workflow.Activities.Rules.RuleConditionReference(); System.Workflow.Activities.Rules.RuleConditionReference ruleconditionreference2 = new System.Workflow.Activities.Rules.RuleConditionReference(); System.Workflow.Activities.Rules.RuleConditionReference ruleconditionreference3 = new System.Workflow.Activities.Rules.RuleConditionReference(); System.Workflow.ComponentModel.ActivityBind activitybind1 = new System.Workflow.ComponentModel.ActivityBind(); System.Workflow.ComponentModel.ActivityBind activitybind2 = new System.Workflow.ComponentModel.ActivityBind(); this.CheckUniqueness = new System.Workflow.Activities.CodeActivity(); this.ThrowError = new System.Workflow.Activities.CodeActivity(); this.UpdateResourceActivity1 = new Microsoft.ResourceManagement.Workflow.Activities.UpdateResourceActivity(); this.InitializeUpdateTarget = new System.Workflow.Activities.CodeActivity(); this.enumerateResourcesActivity1 = new Microsoft.ResourceManagement.Workflow.Activities.EnumerateResourcesActivity(); this.InitializeEnumerateResource = new System.Workflow.Activities.CodeActivity(); this.ifAccountNameNotFound = new System.Workflow.Activities.IfElseBranchActivity(); this.ifAccountNameFound = new System.Workflow.Activities.IfElseBranchActivity(); this.sequenceActivity1 = new System.Workflow.Activities.SequenceActivity(); this.ifElseActivity1 = new System.Workflow.Activities.IfElseActivity(); this.whileActivity1 = new System.Workflow.Activities.WhileActivity(); this.GenerateUniqueAccountName = new System.Workflow.Activities.CodeActivity(); this.readResourceActivity1 = new Microsoft.ResourceManagement.Workflow.Activities.ReadResourceActivity(); this.InitializeReadResource = new System.Workflow.Activities.CodeActivity(); this.CurrentRequestActivity1 = new Microsoft.ResourceManagement.Workflow.Activities.CurrentRequestActivity(); // // CheckUniqueness // this.CheckUniqueness.Name = "CheckUniqueness"; this.CheckUniqueness.ExecuteCode += new System.EventHandler(this.CheckUniqueness_ExecuteCode); // // ThrowError // this.ThrowError.Name = "ThrowError"; this.ThrowError.ExecuteCode += new System.EventHandler(this.ThrowError_ExecuteCode); // // UpdateResourceActivity1 // this.UpdateResourceActivity1.ActorId = new System.Guid("00000000-0000-0000-0000-000000000000"); this.UpdateResourceActivity1.Name = "UpdateResourceActivity1"; this.UpdateResourceActivity1.ResourceId = new System.Guid("00000000-0000-0000-0000-000000000000"); this.UpdateResourceActivity1.UpdateParameters = new Microsoft.ResourceManagement.WebServices.WSResourceManagement.UpdateRequestParameter[0]; // // InitializeUpdateTarget // this.InitializeUpdateTarget.Name = "InitializeUpdateTarget"; this.InitializeUpdateTarget.ExecuteCode += new System.EventHandler(this.InitializeUpdateTarget_ExecuteCode); // // enumerateResourcesActivity1 // this.enumerateResourcesActivity1.Activities.Add(this.CheckUniqueness); this.enumerateResourcesActivity1.ActorId = new System.Guid("00000000-0000-0000-0000-000000000000"); this.enumerateResourcesActivity1.Name = "enumerateResourcesActivity1"; this.enumerateResourcesActivity1.PageSize = 100; this.enumerateResourcesActivity1.Selection = null; this.enumerateResourcesActivity1.SortingAttributes = null; this.enumerateResourcesActivity1.TotalResultsCount = 0; this.enumerateResourcesActivity1.XPathFilter = null; // // InitializeEnumerateResource // this.InitializeEnumerateResource.Name = "InitializeEnumerateResource"; this.InitializeEnumerateResource.ExecuteCode += new System.EventHandler(this.InitializeEnumerateResource_ExecuteCode); // // ifAccountNameNotFound // this.ifAccountNameNotFound.Activities.Add(this.ThrowError); ruleconditionreference1.ConditionName = "AccountNotFound"; this.ifAccountNameNotFound.Condition = ruleconditionreference1; this.ifAccountNameNotFound.Name = "ifAccountNameNotFound"; // // ifAccountNameFound // this.ifAccountNameFound.Activities.Add(this.InitializeUpdateTarget); this.ifAccountNameFound.Activities.Add(this.UpdateResourceActivity1); ruleconditionreference2.ConditionName = "AccountFound"; this.ifAccountNameFound.Condition = ruleconditionreference2; this.ifAccountNameFound.Name = "ifAccountNameFound"; // // sequenceActivity1 // this.sequenceActivity1.Activities.Add(this.InitializeEnumerateResource); this.sequenceActivity1.Activities.Add(this.enumerateResourcesActivity1); this.sequenceActivity1.Name = "sequenceActivity1"; // // ifElseActivity1 // this.ifElseActivity1.Activities.Add(this.ifAccountNameFound); this.ifElseActivity1.Activities.Add(this.ifAccountNameNotFound); this.ifElseActivity1.Name = "ifElseActivity1"; // // whileActivity1 // this.whileActivity1.Activities.Add(this.sequenceActivity1); ruleconditionreference3.ConditionName = "LoopAgain"; this.whileActivity1.Condition = ruleconditionreference3; this.whileActivity1.Name = "whileActivity1"; // // GenerateUniqueAccountName // this.GenerateUniqueAccountName.Name = "GenerateUniqueAccountName"; this.GenerateUniqueAccountName.ExecuteCode += new System.EventHandler(this.GenerateUniqueAccountName_ExecuteCode); // // readResourceActivity1 // this.readResourceActivity1.ActorId = new System.Guid("00000000-0000-0000-0000-000000000000"); this.readResourceActivity1.Name = "readResourceActivity1"; activitybind1.Name = "AddUniqueAccountName"; activitybind1.Path = "readResourceActivity1_Resource1"; this.readResourceActivity1.ResourceId = new System.Guid("00000000-0000-0000-0000-000000000000"); this.readResourceActivity1.SelectionAttributes = null; this.readResourceActivity1.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.ReadResourceActivity.ResourceProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind1))); // // InitializeReadResource // this.InitializeReadResource.Name = "InitializeReadResource"; this.InitializeReadResource.ExecuteCode += new System.EventHandler(this.InitializeReadResource_ExecuteCode); // // CurrentRequestActivity1 // activitybind2.Name = "AddUniqueAccountName"; activitybind2.Path = "CurrentRequestActivity1_CurrentRequest1"; this.CurrentRequestActivity1.Name = "CurrentRequestActivity1"; this.CurrentRequestActivity1.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.CurrentRequestActivity.CurrentRequestProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind2))); // // AddUniqueAccountName // this.Activities.Add(this.CurrentRequestActivity1); this.Activities.Add(this.InitializeReadResource); this.Activities.Add(this.readResourceActivity1); this.Activities.Add(this.GenerateUniqueAccountName); this.Activities.Add(this.whileActivity1); this.Activities.Add(this.ifElseActivity1); this.Name = "AddUniqueAccountName"; this.CanModifyActivities = false; } #endregion private SequenceActivity sequenceActivity1; private WhileActivity whileActivity1; private CodeActivity CheckUniqueness; private Microsoft.ResourceManagement.Workflow.Activities.EnumerateResourcesActivity enumerateResourcesActivity1; private CodeActivity InitializeEnumerateResource; private CodeActivity InitializeReadResource; private Microsoft.ResourceManagement.Workflow.Activities.ReadResourceActivity readResourceActivity1; private CodeActivity InitializeUpdateTarget; private IfElseBranchActivity ifAccountNameNotFound; private IfElseBranchActivity ifAccountNameFound; private IfElseActivity ifElseActivity1; private CodeActivity ThrowError; private CodeActivity GenerateUniqueAccountName; private Microsoft.ResourceManagement.Workflow.Activities.UpdateResourceActivity UpdateResourceActivity1; private Microsoft.ResourceManagement.Workflow.Activities.CurrentRequestActivity CurrentRequestActivity1; } I am NOT sure what I am doing wrong here. I also read when you use EnumerateResource you may not want to use while loop but I am not sure how we can enumerate results once you get from EnumerateResourceActivity. I would really appreciate you if you suggest any solution/better approach to this. Thanks, Bhavesh Patel
July 24th, 2012 1:55pm

Hi Bhavesh! To me it looks like you've made a bit to complicated workflow just to generate a unique value. 1. To start with I recommend you to skip the CurrentRequestActivity just for getting the current ResourceID, it's a lot easier and nicer to use the TryGetContainingWorkflow function and why not in a Property like this: protected SequentialWorkflow ContainingWorkflow { get { SequentialWorkflow containingWorkflow; if (!SequentialWorkflow.TryGetContainingWorkflow(this, out containingWorkflow)) throw new InvalidOperationException("Unable to get Containing Workflow"); return containingWorkflow; } } The reason I have it protected is that I usually have it in a base class for my activitites. Using the Containing Workflow allows you to get all sorts of information from the parent workflow including the current ResourceID like this: ContainingWorkflow.TargetId 2. The XPath Query string you are using for the EnumerateResources Activity tells me you might have been doing VB Before :-) how about you format it like this instead (and you don't have to escape single quotes in strings and this could be the problem)? enumerateResourcesActivity1.XPathFilter = string.Format("/{0}[AccountName='{1}']", resourceType, AccountName); 3. You have added a child activity to the EnumerateResource Activity, this is good when you wish to read or change the Resources found but in you case you only need to find out if any Resources are found right? Becuase if there is one you likely wish to try with another value. Therefore I recommend you to just check the TotalResultsCount property to see if it bigger than 0 to set loopagain to true or false. I could probably give you a lot of hints making this better but I can't say exactly whats wrong except maybe you're escaping the single qoutes in the Query... //HenrikHenrik Nilsson, Forefront Identity Manager MVP Blog Twitter My employer - Cortego
Free Windows Admin Tool Kit Click here and download it now
July 24th, 2012 3:31pm

Hi Henrik, Thank you for your reply. As per your suggestions I have removed the CurrentRequestActivity and changed the XPathFilter but I am encountering the same error I was getting before. Here is the screen shot. Not sure what is wrong here! I would be happy to know how I can make it better. Thanks, Bhavesh Patel
July 24th, 2012 4:48pm

As I said, I dont have any clue what might be wrong so I recommend you to hook a debugger with a breakpoint where you set the filter to try and find out why it turns out being empty... //HenrikHenrik Nilsson, Forefront Identity Manager MVP Blog Twitter My employer - Cortego
Free Windows Admin Tool Kit Click here and download it now
July 24th, 2012 5:12pm

Thank you Henrik. I did attach the debugger before posting question in this forum. In my debugging I saw the control hits the breakpoints and executes private void InitializeEnumerateResource_ExecuteCode(object sender, EventArgs e) and successfully set the XPathFilter, but after that CheckUniqueness_ExecuteCode,InitializeUpdateTarget_ExecuteCode and ThrowError_ExecuteCode never get executed. I understand why it is not executing ThrowError_ExecuteCode but not sure about other two. In addition to this, in the portal I do see couple of hundreds workflow instances each time I try to generate AccountName for a test user. Thanks to all community members. Bhavesh
July 25th, 2012 9:12am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics