WorkflowInvoker.Invoke - Literal only supports value types and the immutable type System.String

650 Views Asked by At

My question may be interpreted as repeated, because of this similar question: Workflow Foundation - Literal only supports value types and the immutable type System.String But in fact, I have tried the solution given to the above (and many other attempts that I could find) and still could not resolve the issue.

In a Workflow Console application, I want to send a DataTable into my own CodeActivity and return it back to Main.

namespace WorkflowConsolePOC
{
    class Program
    {
        static void Main(string[] args)
        {
            //Build some DataTable
            DataTable dtb = new DataTable();
            dtb.Clear();
            dtb.Columns.Add("name");
            dtb.Columns.Add("age");
            DataRow row = dtb.NewRow();
            row["name"] = "Thiago";
            row["age"] = "33";
            dtb.Rows.Add(row);

            string msg = ("Some message" + Environment.NewLine + " Test purpose");

            MyCodeActivity myCodeActivity = new MyCodeActivity();
            myCodeActivity.Message = new InArgument<string>(msg);
            //Passing the DataTable
            //This is the solution given to the existing question:
            myCodeActivity.Entrada = new InArgument<DataTable>(ExpressionServices.Convert((env) => dtb));

            //This was my attempt which results in the same exception, but with 'Literal<DataTable>':...
            //myCodeActivity.Entrada = new InArgument<DataTable>(dtb);

            dtb = WorkflowInvoker.Invoke<DataTable>(myCodeActivity);  // <==== Error

            //Read the first row of the resulting DataTable
            Console.WriteLine(dtb.Rows[0][0].ToString());
        }
    }
}

And this is the code for MyCodeActivity:

namespace WorkflowConsolePOC
{

    public sealed class MyCodeActivity : CodeActivity<DataTable>
    {
        public InArgument<string> Message { get; set; }
        public InArgument<System.Data.DataTable> Entrada { get; set; }

        // If your activity returns a value, derive from CodeActivity<TResult>
        // and return the value from the Execute method.
        protected override DataTable Execute(CodeActivityContext context)
        {
            // Obtain the runtime value of the input arguments
            string codeString = context.GetValue(this.Message);
            //Get the DataTable
            DataTable entrada = context.GetValue<DataTable>(Entrada);

            //Alter the first row, first column
            entrada.Rows[0][0] = "Altered";

            return entrada;
        }
    }
}

My custom activity isn't even hit. The error appears at the WorkflowInvoker.Invoke.

'Literal<<>c__DisplayClass0>': Literal only supports value types and the immutable type System.String. The Type WorkflowConsolePOC.Program+<>c__DisplayClass0 cannot be used as a literal.

What am I missing here? I am stuck at this for three days. I kindly ask for your help. Thanks!

1

There are 1 best solutions below

0
Mo Chavoshi On

This is the correct way of setting reference types:

myCodeActivity.Entrada = new InArgument<DataTable>((ctx) => dtb);

Or you can invoke and pass the arguments like this:

MyCodeActivity myCodeActivity = new MyCodeActivity();

var arguments = new Dictionary<String, Object>
{
    { "Message",  msg },
    { "Entrada",  dtb },
};

dtb = WorkflowInvoker.Invoke<DataTable>(myCodeActivity, arguments);