locked
Passing parameters of type List<> from a web application to the Receive activity of a workflow service RRS feed

  • Question

  • Hello,

    I have a Recieve activity with the following parameters in the Content property.  Using generic parameter names here:

    - parameter1 of type Object1 assigned to Parameter1 variable

    - parameter2 of type List<Object2> assigned to Parameter2 variable.  Note - default value of Parameter2 variable = New List(Of Object2)()

    - parameter3 of type Object3 assigned to Parameter3 variable

    In my web application, I create a service reference and create a client as such:

     

    SomeWFServiceClient client = null
    ;
    
    try
    
    {
     client = new
     SomeWFServiceClient();
     List<Object2> listOfObject2 = new
     List<Object2> { new
     Object2 {Id=1, Name="SomeName"
    , Type="Customer"
     }, };
    
    client.ProcessSomething(Object1, listOfObject2, Object3);
    }
    catch
    
    {
    }
    finally
    
    {
     client.Close();
    }
    
    I have a breakpoint at the Receive activity.  When I look at the values that get assigned to the Receive activity parameters, I see that parameter1 and parameter3 get the values that were passed from the web application.  However, parameter2 shows a Count of 1, but in the Item property, it shows this error: system.reflection.targetparametercountexception and in the Message, I get: parameter count mismatch .

     

    When I type parameter2[0] in the Immediate window, I see the same error information.

    The Receive activity expects 3 parameters and is passed 3 parameters.  Why am I getting this error?

    Thanks in advance for the help!

     

    Monday, October 4, 2010 9:39 PM

Answers

  • Hy vonsazkin,

    As said by patrick, you'll have to use LambdaValue to pass byref argument to your workflow.

    Look this sample for more explain :

    List<Object2> objs = new List<Object2>(); // Add your data to list<> after this code
    Workflow1 workflow = new Workflow1() { Argument1 = new LambdaValue<List<Object2>>(c => objs) }; 
    WorkflowInvoker.Invoke(workflow); 
    
    
    

    You can found more explain on my french blog :

    http://blogs.codes-sources.com/jeremyjeanson/archive/2010/03/22/wf4-passage-d-arguments-literal-visualbasicvalue-ou-lambdavalue.aspx

     


    Jérémy Jeanson MVP, MCP, MCTS http://blogs.codes-sources.com/JeremyJeanson/ (French or English spoken)
    • Proposed as answer by JeremyJeansonMVP Tuesday, October 5, 2010 8:04 AM
    • Marked as answer by vonsazkin Wednesday, October 6, 2010 8:35 PM
    Tuesday, October 5, 2010 8:04 AM
  • Can you post the code to the receive activity and how you create the parameters content? Are you using the designer or code? I whipped up a quick designer example, with a Receive that takes a List<Class1> and I pass it in like this:

    ServiceClient client = new ServiceClient();
    
    // Use the 'client' variable to call operations on the service.
    List<Class1> list = new List<Class1>();
    list.Add(new Class1 { Name = "Steve", Id = 1 });
    list.Add(new Class1 { Name = "Bill", Id = 2 });
    // Always close the client.
    string response = client.GetData(list);
    Console.WriteLine(response);
    client.Close();
    

    This is just fine, you can pass in arrays or other reference types as the parameters to a service operation, it sounds like there might be some sort of mixup in your receive parameters content, or else some other misconfiguration. When you added the service reference to the client, did you go to the advanced tab and specify what .NET collection type you wanted to use? The default is Array, but you can also specificy generic List. In my example above it did not work until I added a second service reference and specific generic list as the collection type.

    Steve Danielson [Microsoft]
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm

     

    • Marked as answer by vonsazkin Wednesday, October 6, 2010 8:35 PM
    Wednesday, October 6, 2010 4:35 PM
  • In order to pass and retrieve reference types into workflow, you'll need to use a wrapper to return the value as a delegate- this was a change in the RTM version of the product. Please see the following article for details on how to do this:

    http://social.technet.microsoft.com/wiki/contents/articles/using-reference-type-arguments-in-a-workflow-wf.aspx

    • Marked as answer by vonsazkin Wednesday, October 6, 2010 8:35 PM
    Monday, October 4, 2010 9:45 PM
  • Steve and I spoke about this - from what I see in your question it looks like your workflow service works but you are concerned about the exception in the debugger. 

    I don't have an answer as to why you see this exception in the debugger but I can say that it is very common in the debugger to get exceptions of various kinds as it tries to evaluate values.

    Bottom line... if your workflow service is working as expected (not aborting due to unhandled exception) then I wouldn't worry about this.  On the other hand if you are getting an unhandled exception at runtime then let us know what that exception is - we might be able to help you with that.


    http://blogs.msdn.com/rjacobs
    • Marked as answer by vonsazkin Wednesday, October 6, 2010 8:35 PM
    Wednesday, October 6, 2010 7:09 PM

All replies

  • In order to pass and retrieve reference types into workflow, you'll need to use a wrapper to return the value as a delegate- this was a change in the RTM version of the product. Please see the following article for details on how to do this:

    http://social.technet.microsoft.com/wiki/contents/articles/using-reference-type-arguments-in-a-workflow-wf.aspx

    • Marked as answer by vonsazkin Wednesday, October 6, 2010 8:35 PM
    Monday, October 4, 2010 9:45 PM
  • Thanks for the link.  However, I didn't quite understand this.  How do I change the code in the web application so I can pass the list of objects to the WF function?
    Monday, October 4, 2010 9:51 PM
  • Hy vonsazkin,

    As said by patrick, you'll have to use LambdaValue to pass byref argument to your workflow.

    Look this sample for more explain :

    List<Object2> objs = new List<Object2>(); // Add your data to list<> after this code
    Workflow1 workflow = new Workflow1() { Argument1 = new LambdaValue<List<Object2>>(c => objs) }; 
    WorkflowInvoker.Invoke(workflow); 
    
    
    

    You can found more explain on my french blog :

    http://blogs.codes-sources.com/jeremyjeanson/archive/2010/03/22/wf4-passage-d-arguments-literal-visualbasicvalue-ou-lambdavalue.aspx

     


    Jérémy Jeanson MVP, MCP, MCTS http://blogs.codes-sources.com/JeremyJeanson/ (French or English spoken)
    • Proposed as answer by JeremyJeansonMVP Tuesday, October 5, 2010 8:04 AM
    • Marked as answer by vonsazkin Wednesday, October 6, 2010 8:35 PM
    Tuesday, October 5, 2010 8:04 AM
  • Can you post the code to the receive activity and how you create the parameters content? Are you using the designer or code? I whipped up a quick designer example, with a Receive that takes a List<Class1> and I pass it in like this:

    ServiceClient client = new ServiceClient();
    
    // Use the 'client' variable to call operations on the service.
    List<Class1> list = new List<Class1>();
    list.Add(new Class1 { Name = "Steve", Id = 1 });
    list.Add(new Class1 { Name = "Bill", Id = 2 });
    // Always close the client.
    string response = client.GetData(list);
    Console.WriteLine(response);
    client.Close();
    

    This is just fine, you can pass in arrays or other reference types as the parameters to a service operation, it sounds like there might be some sort of mixup in your receive parameters content, or else some other misconfiguration. When you added the service reference to the client, did you go to the advanced tab and specify what .NET collection type you wanted to use? The default is Array, but you can also specificy generic List. In my example above it did not work until I added a second service reference and specific generic list as the collection type.

    Steve Danielson [Microsoft]
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm

     

    • Marked as answer by vonsazkin Wednesday, October 6, 2010 8:35 PM
    Wednesday, October 6, 2010 4:35 PM
  • Steve,

    I used the designer to create the activities in the workflow.  What I have is this:

    - A website

    - A master workflow

    - An agent workflow

    The web site invokes the master workflow and the master workflow in turn calls the operations on the agent workflow using correlation.  When I added the service reference to the master workflow in the web site, I did specify Generic List as the .NET collection type. 

    Please see the images in the following link: http://img831.imageshack.us/gal.php?g=screen1uh.png

    Screen1: Receive activity in the master workflow.

    Screen2: the deploymentRequest object being created and the website invoking the master workflow and passing this object to it.  Note that the deploymentRequest object contains Lists of objects.

    Note the Locals window in Screen3.png.  For example: the DestinationServers is showing the exception at runtime, while the FromEnvironment has proper values.  DestinationServers is a List<Resource> property of the deploymentRequest object and FromEnvironment is a Environment type property of the deploymentRequest object.

    Private fields of the deploymentRequest object:

    private int _id;
        private string _description;
        private User _user;
        private Client _client;
        private Deployment.Services.Environment _fromEnvironment;
        private Deployment.Services.Environment _toEnvironment;
        private string _notes;
        private string _additionalContacts;
        private DateTime _deploymentTime;
        private DateTime _startTime;
        private DateTime _endTime;
        private DeploymentStatus _status;
        private List<Application> _applications;
        private List<Contact> _contacts;
        private List<Resource> _sourceAgents;
        private List<Resource> _destinationAgents;
        private List<Resource> _sourceServers;
        private List<Resource> _destinationServers;
        private Resource _indexBuildServer;

     

    • Marked as answer by vonsazkin Wednesday, October 6, 2010 8:35 PM
    • Unmarked as answer by vonsazkin Wednesday, October 6, 2010 8:35 PM
    Wednesday, October 6, 2010 5:38 PM
  • Steve and I spoke about this - from what I see in your question it looks like your workflow service works but you are concerned about the exception in the debugger. 

    I don't have an answer as to why you see this exception in the debugger but I can say that it is very common in the debugger to get exceptions of various kinds as it tries to evaluate values.

    Bottom line... if your workflow service is working as expected (not aborting due to unhandled exception) then I wouldn't worry about this.  On the other hand if you are getting an unhandled exception at runtime then let us know what that exception is - we might be able to help you with that.


    http://blogs.msdn.com/rjacobs
    • Marked as answer by vonsazkin Wednesday, October 6, 2010 8:35 PM
    Wednesday, October 6, 2010 7:09 PM
  • Ron, Steve,

    I much appreciate the help with this.  I do get a runtime exception in the Try/Catch activity in the workflow.

    As mentioned in my previous post, the deploymentRequestObject has a List<Applications> property.

    In the screenshots in the link (http://img215.imageshack.us/i/screen1cu.png/ ), I do a ForEach application in DeploymentRequest.Applications activity in the master workflow.

    I then pass the application object and the list of Resources using a Send activity in the master workflow and call the DetachDatabase operation in the agent workflow service.  The application object gets passed fine with all the values assigned.  However, the list of Resources does not.

    In screen2 (http://img683.imageshack.us/i/screen2vc.png/ ), in the ParallelForEach<Resource> activity in the agent workflow, an error is thrown in the Catch (see screen3: http://img409.imageshack.us/i/screen3q.png/ ):

            Text    "Error: System.InvalidOperationException: Values must be bound to a non-null expression before ParallelForEach activity 'ParallelForEach<Resource>' can be used.
       at System.Activities.Statements.ParallelForEach`1.Execute(NativeActivityContext context)
       at System.Activities.NativeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager)
       at System.Activities.ActivityInstance.Execute(ActivityExecutor executor, BookmarkManager bookmarkManager)
       at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)"    System.String

    Wednesday, October 6, 2010 7:56 PM
  • I figured it out.  A silly error:  I was passing the list of Resources from the master to the agent without setting it's default value to DeploymentRequest.SourceServers.  It seems to be working now.  Thanks a lot for the help with this!
    Wednesday, October 6, 2010 8:37 PM
  • Awesome, glad it is working.

     

    Steve

    Thursday, October 7, 2010 2:25 AM