none
Using custom types as input/ouput parameters RRS feed

  • Question

  • Hello,

    I am using a custom type for input parameter for my workflow but I get the following error message, when invoking the activity:

    The following errors were encountered while processing the workflow tree:
    'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "argument1.Title".
    'argument1' is not declared. It may be inaccessible due to its protection level.

    And here is my code:

    Dictionary<String, object> activityParams = new Dictionary<string, object>();
    activityParams.Add("oldValue", new Movie { Title = "My fictional movie" });
    
    XamlSchemaContext ctx = new DynamicXamlSchemaContext();
    XamlReader reader = ActivityXamlServices.CreateBuilderReader(new XamlXmlReader(@"..\..\Activity2.xaml" , ctx));
    ActivityBuilder ab = XamlServices.Load(reader) as ActivityBuilder;
    
    VisualBasicSettings vbSettings = new VisualBasicSettings();
    vbSettings.ImportReferences.Add(GetVBImportReference(typeof(Movie)));
    VisualBasic.SetSettingsForImplementation(ab, vbSettings);
    
    DynamicActivity activity = new DynamicActivity { Implementation = () => ab.Implementation };
    foreach (var item in ab.Properties)
    	activity.Properties.Add(item);
    
    WorkflowInvoker invoker = new WorkflowInvoker(activity);
    IDictionary<string, object> activityOutput = invoker.Invoke(activityParams, TimeSpan.FromSeconds(30));
    

    The problem is somehow related to the custom type I am using, because if I replace it with String - than it works okay. I already tried several things, such as setting the imports (see the code snippet) or removing the "sad:XamlDebuggerXmlReader.FileName" attribute, but to no avail. I am getting the error message at runtime.

    And here is the xaml file:
    <Activity mc:Ignorable="sap" x:Class="WorkflowConsoleApplication1.Activity2" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:local="clr-namespace:WorkflowConsoleApplication1.EntityService" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:s4="clr-namespace:System;assembly=System.ServiceModel" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:srs="clr-namespace:System.Runtime.Serialization;assembly=System.Runtime.Serialization" xmlns:srs1="clr-namespace:System.Runtime.Serialization;assembly=mscorlib" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
     <x:Members>
      <x:Property Name="argument1" Type="InArgument(local:Movie)" />
      <x:Property Name="argument3" Type="OutArgument(x:String)" />
     </x:Members>
     <sap:VirtualizedContainerService.HintSize>304,323</sap:VirtualizedContainerService.HintSize>
     <mva:VisualBasic.Settings>Assembly references and imported namespaces for internal implementation</mva:VisualBasic.Settings>
     <Sequence sad:XamlDebuggerXmlReader.FileName="C:\Users\s7orm\Desktop\WorkflowConsoleApplication1\WorkflowConsoleApplication1\Activity2.xaml" sap:VirtualizedContainerService.HintSize="264,283">
      <sap:WorkflowViewStateService.ViewState>
       <scg3:Dictionary x:TypeArguments="x:String, x:Object">
        <x:Boolean x:Key="IsExpanded">True</x:Boolean>
       </scg3:Dictionary>
      </sap:WorkflowViewStateService.ViewState>
      <Assign sap:VirtualizedContainerService.HintSize="242,58">
       <Assign.To>
        <OutArgument x:TypeArguments="x:String">[argument3]</OutArgument>
       </Assign.To>
       <Assign.Value>
        <InArgument x:TypeArguments="x:String">[argument1.Title]</InArgument>
       </Assign.Value>
      </Assign>
      <WriteLine sap:VirtualizedContainerService.HintSize="242,61" Text="[argument3]" />
     </Sequence>
    </Activity>

    Thanks in advance.

    • Edited by Krassi Valev Wednesday, March 2, 2011 7:52 PM formatting again
    Wednesday, March 2, 2011 6:41 PM

Answers

  • So I finally figured it out. The first part of the solution is:

    1) in order to use custom objects as In and Out Arguments - the classes have to be declared in another dll (not in the one, where the workflow resides)

    and now comes the second and weird part:

    2) your custom object should NOT implement System.Runtime.Serialization.IExtensibleDataObject

    If it does, well... it is game over - you get the error message, that the type may be inaccessible due to its protection level. In my case Movie was a type generated from a web service reference, so it automatically implemented said interface. As soon as I modified the generated class so that it does not implement IExtensibleDataObject - it worked fine.

    Can someone from the WF team investigate into this issue?

     

    Regards

    Krassi

    • Marked as answer by Krassi Valev Wednesday, March 2, 2011 11:43 PM
    Wednesday, March 2, 2011 11:43 PM

All replies

  • Can you show the xaml for the custom activity and also where you declare and populate the activityParams?

    Thanks,

     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

    Wednesday, March 2, 2011 7:27 PM
    Moderator
  • Hello Steve,

    thanks for the reply. I updated my original post with the param declaration and the activity xaml.

    Wednesday, March 2, 2011 7:53 PM
  • I see it. One follow up question, why do you load into an ActivityBuilder, and then create a DynamicActivity that uses the ActivityBuilderas its implementation? ActivityXamlServices.Load returns a DynamicActivity. And then you could just invoke that. If you want to use an ActivityBuilder, that is mostly used for working with workflow definitions, editing them, and serializing to Xaml (although they are very similar and it sounds like it is working for you if Movie is replaced with string). What happens if you return an ActivityBuilder from the call to ActivityXamlServices.Load and then invoke?


    Here is also some additional information about DynamicActivity and ActivityBuilder:
    http://msdn.microsoft.com/en-us/library/ff458319.aspx


    Thanks,
    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

    Wednesday, March 2, 2011 8:05 PM
    Moderator
  • I get another error message, this time in the Load() method:

     

    'The type ‘InArgument(local:Movie)’ of property ‘argument1’ could not be resolved.' Line number '3' and line position '34'.
    And here is the code
    // activity params are the same
    
    DynamicActivity activity = ActivityXamlServices.Load(@"..\..\Activity2.xaml") as DynamicActivity;
    
    VisualBasicSettings vbSettings = new VisualBasicSettings();
    vbSettings.ImportReferences.Add(GetVBImportReference(typeof(Movie)));
    VisualBasic.SetSettings(activity, vbSettings);
    
    // invoke is the same
    

    This is the reason I used the other code in the first place - there I have my own custom XamlSchemaContext, where I catch the types, that cannot be initialized correctly and map them to the correct type - here is the code for the mapping (at this stage it is more or less proof of concept)

    protected override XamlType GetXamlType(string xamlNamespace, string name, params XamlType[] typeArguments)
    {
    	var t = base.GetXamlType(xamlNamespace, name, typeArguments);
    
    	if (t == null)
    	{
    		if (name == "Movie")
        		t = new XamlType(typeof(Movie), this);
    		}
    
    	return t;
    }
    

     

    Wednesday, March 2, 2011 8:21 PM
  • So I finally figured it out. The first part of the solution is:

    1) in order to use custom objects as In and Out Arguments - the classes have to be declared in another dll (not in the one, where the workflow resides)

    and now comes the second and weird part:

    2) your custom object should NOT implement System.Runtime.Serialization.IExtensibleDataObject

    If it does, well... it is game over - you get the error message, that the type may be inaccessible due to its protection level. In my case Movie was a type generated from a web service reference, so it automatically implemented said interface. As soon as I modified the generated class so that it does not implement IExtensibleDataObject - it worked fine.

    Can someone from the WF team investigate into this issue?

     

    Regards

    Krassi

    • Marked as answer by Krassi Valev Wednesday, March 2, 2011 11:43 PM
    Wednesday, March 2, 2011 11:43 PM
  • I will follow up with the WF team on this.

    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

    Thursday, March 3, 2011 3:16 PM
    Moderator
  • Wow, I thought I was going completely crazy on this. Thanks for posting this, it's the exact same problem that I am facing.

    Now I will need to find a solution...

     

    --edit--

    Solution found, I'm not sure if this goes for the original poster as well but I had my workflow consist of a nested workflow, the host in project a and the detailed workflow in project b.
    Project b has a web reference that provides a custom type that implements the IExtensibleDataObject and that was used by the workflow in project b. Since all was fine there I saw no error markings on the workflow. However today I opened the host and noticed that it did give an error there.

    A simple import of System.Runtime.Serialization (in the workflow in project a) fixed all of that.


    • Edited by FlorensH Wednesday, October 26, 2011 7:40 AM
    • Proposed as answer by FlorensH Wednesday, October 26, 2011 7:41 AM
    Tuesday, October 25, 2011 3:23 PM