C# 从xaml获取输入参数,并通过MVC3将其用于WF4中的动态活动

C# 从xaml获取输入参数,并通过MVC3将其用于WF4中的动态活动,c#,asp.net,asp.net-mvc-3,workflow-foundation-4,workflow-activity,C#,Asp.net,Asp.net Mvc 3,Workflow Foundation 4,Workflow Activity,我正在尝试制作一个可以在xaml中重用的本机活动,它基本上复制了WF3.x中PolicyActivity的功能,WF3.x是一个带有GUI来编辑规则的规则引擎 我的问题是,当我调用WorkflowInvoker.Invoke时,它会说模型,即inagrament是Null,我知道这并不是因为该代码作为一个函数返回活动,就像Frode Nilsen的博客中那样: 我的问题是,我是否正确地从Xaml活动中获取了inagrament public sealed class RuleSequenceA

我正在尝试制作一个可以在xaml中重用的本机活动,它基本上复制了WF3.x中PolicyActivity的功能,WF3.x是一个带有GUI来编辑规则的规则引擎

我的问题是,当我调用
WorkflowInvoker.Invoke
时,它会说模型,即
inagrament
Null
,我知道这并不是因为该代码作为一个函数返回活动,就像Frode Nilsen的博客中那样: 我的问题是,我是否正确地从Xaml活动中获取了
inagrament

 public sealed class RuleSequenceAcitvity : NativeActivity<Sequence>
{
    private Sequence _sequence;
    InArgument<HomeIndexViewModel> Model { get; set; } //Same name as inArgument in xaml

    protected override void Execute(NativeActivityContext context)
    {
        populateSequence();
        var input = new Dictionary<string, object>();
        //The following line is giving me the Null Argument Exception
        var model = context.GetValue<HomeIndexViewModel>(this.Model);
        input.Add("Model", model);
        WorkflowInvoker.Invoke(_sequence, input);

    }

    private void populateSequence()
    {
        //get the list of rules from repository
        var rules = ObjectFactory.Container.GetInstance<IRuleRepository>().Rules.ToList();

        //Declare a dynamic property as the view model
        var inProperty = new DynamicActivityProperty
        {
            Name = "Model",
            Type = typeof(InArgument<HomeIndexViewModel>),
            Value = Model
        };
        var activity = new DynamicActivity() { Properties = { inProperty } };

        //Import references
        Common.AddVbSetting(activity);

        _sequence = new Sequence();
        activity.Implementation = () => _sequence;

        //Sort Descending - those added first are lowest priority
        var sortedRules = rules.OrderBy(x => x.Priority).ToList();

        foreach (var inRule in rules)
        {
            var outRule = RuleConverter.ToIfActivity(inRule);
            _sequence.Activities.Add(outRule);
        }

    }
}
公共密封类规则sequenceacitivity:NativeActivity
{
私有序列_序列;
InArgument模型{get;set;}//与xaml中的InArgument同名
受保护的覆盖无效执行(NativeActivityContext上下文)
{
流行序列();
var输入=新字典();
//下面一行给出了Null参数异常
var model=context.GetValue(this.model);
输入。添加(“模型”,模型);
WorkflowInvoker.Invoke(_序列,输入);
}
私有void populateSequence()
{
//从存储库获取规则列表
var rules=ObjectFactory.Container.GetInstance().rules.ToList();
//将动态属性声明为视图模型
var inProperty=新的DynamicActivityProperty
{
Name=“Model”,
类型=类型(无粘性),
价值=模型
};
var activity=new DynamicActivity(){Properties={inProperty};
//导入引用
公共。添加设置(活动);
_序列=新序列();
activity.Implementation=()=>\u序列;
//按降序排序-先添加的是优先级最低的
var sortedRules=rules.OrderBy(x=>x.Priority.ToList();
foreach(规则中的var规则)
{
var outRule=规则转换器.ToFactivity(规则);
_顺序。活动。添加(排除规则);
}
}
}
}你就快到了

首先,您必须将您的
inagrament
声明为public。否则,无论哪个调用活动,都无法将其输入绑定到该活动

第二,接收输入参数的不是您的
\u序列
。您必须调用并传递参数的是动态活动,而不是序列

最后,您正确地创建了
DynamicActivityProperty
,但在这种情况下,您不需要设置它的值。当您使用名为
“Model”
的输入调用
Workflow.Invoker()
时,相同的输入将绑定到动态属性

我刚刚编辑了你的代码,没有运行它。希望有帮助!:)

公共密封类规则sequenceacitivity:NativeActivity
{
私有动态性_动态性;
公共InArgument模型{get;set;}
受保护的覆盖无效执行(NativeActivityContext上下文)
{
PopulatedDynamicActivity();
var输入=新字典();
//它抛出了一个空引用,因为模型
//是私有的,因此活动正在接收的输入
//他从来没有被束缚过。
var model=context.GetValue(this.model);
输入。添加(“模型”,模型);
//它是包含输入参数的动态活动。
//不是序列。
WorkflowInvoker.Invoke(_dynamicActivity,input);
}
私有void populatedDynamicActivity()
{
//从存储库获取规则列表
风险值规则=
对象工厂
.集装箱
.GetInstance()
.规则
.ToList();
//将动态属性声明为视图模型
var inProperty=新的DynamicActivityProperty
{
Name=“Model”,
类型=类型(不一致)
};
_dynamicActivity=新的dynamicActivity()
{ 
属性={inProperty}
};
//导入引用
公共。添加设置(活动);
变量序列=新序列();
activity.Implementation=()=>序列
//按降序排序-先添加的是优先级最低的
var sortedRules=rules.OrderBy(x=>x.Priority.ToList();
foreach(规则中的var规则)
{
var outRule=规则转换器.ToFactivity(规则);
顺序。活动。添加(排除规则);
}
}
}

作为一个更新,我刚刚检查了XAML中的inagrament,Model,并按原样填充它。这种从上下文中获取不确定信息的方法与每个新代码活动的股票代码中描述的方法相同,但由于某些原因,它在我的案例中不起作用。非常感谢您的回答和建议。我确实需要改变你指出的那些事情,我感谢你让我知道。然而,即使在公开了inagrament之后,“var model=context.GetValue(this.model);”中的模型值仍然为空。关于为什么不能从xaml中获取值,有什么建议吗?几乎可以肯定,因为您的xaml没有将
Model
参数传递给
ruleSequenceACITIVITY
活动,但我只能在出售xaml本身之后说些什么,尽管我无法手动编辑xaml。你为什么不使用工作流设计器?我实际上在使用设计器。我对WF还是很陌生,所以我想我可以互换使用“xaml”和“designer”。在我的设计器中,我有一个名为Model的Inagument,它的类型是正确的。那么,您确定从设计器获取参数的代码是正确的吗?我刚刚意识到我必须在子活动的属性面板中指定模型参数,而不仅仅是在活动参数面板中。谢谢你的帮助!
public sealed class RuleSequenceAcitvity : NativeActivity<Sequence>
{
    private DynamicActivity _dynamicActivity;
    public InArgument<HomeIndexViewModel> Model { get; set; }

    protected override void Execute(NativeActivityContext context)
    {
        populateDynamicActivity();

        var input = new Dictionary<string, object>();

        // It was throwing a null reference because Model
        // was private, so the input that the activity was receiving 
        // was never binded to it.

        var model = context.GetValue<HomeIndexViewModel>(this.Model);
        input.Add("Model", model);

        // It's the dynamic activity that contains input arguments.
        // Not the sequence. 

        WorkflowInvoker.Invoke(_dynamicActivity, input);
    }

    private void populateDynamicActivity()
    {
        //get the list of rules from repository
        var rules = 
            ObjectFactory
            .Container
            .GetInstance<IRuleRepository>()
            .Rules
            .ToList();

        //Declare a dynamic property as the view model
        var inProperty = new DynamicActivityProperty
        {
            Name = "Model",
            Type = typeof(InArgument<HomeIndexViewModel>)
        };

        _dynamicActivity = new DynamicActivity() 
        { 
            Properties = { inProperty } 
        };

        //Import references
        Common.AddVbSetting(activity);

        var sequence = new Sequence();
        activity.Implementation = () => sequence

        //Sort Descending - those added first are lowest priority
        var sortedRules = rules.OrderBy(x => x.Priority).ToList();

        foreach (var inRule in rules)
        {
            var outRule = RuleConverter.ToIfActivity(inRule);
            sequence.Activities.Add(outRule);
        }

    }
}