如何在ViewState中保存lambda表达式并将其检索回来?

时间:2017-10-01 12:27:26

标签: c# asp.net linq lambda viewstate

我创建了一个自定义user control,它包含一个私有属性和一个公共方法,如下所示:

private dynamic OptionalPredicate { get;set; }

public void SetOptionalPredicate<T>(Expression<Func<T, bool>> value)
{
            OptionalPredicate = value;
}

我有一个包含自定义用户控件的两个实例的webform。 在我的webform中的单击事件中,我调用SetOptionalPredicate方法为其中一个用户控件设置默认谓词,因为您可以看到该方法在上面的代码中执行的操作。

我有以下问题:

在我为其调用SetOptionalPredicate方法的第二个usercontrol中回发后,OptionalPredicate的值变为null

我知道在postback之后所有变量都变为空。所以答案可能是使用ViewState。我搜索了网络,但没有找到关于如何在lambda expression中保存和检索ViewState的答案。

我尝试了以下代码,但它不起作用:

private dynamic OptionalPredicate
        {
            get
            {
                if (this.ViewState[this.ClientID + "OptionalPredicate"] != null)
                {
                    return this.ViewState[this.ClientID + "OptionalPredicate"] as dynamic;
                }
                else
                {
                    return default(dynamic);
                }
            }
            set
            {
                this.ViewState[this.ClientID + "OptionalPredicate"] = value;
            }
        }

我得到以下异常:

Type 'System.Linq.Expressions.Expression`1[[System.Func`2[[APA.Model.Models.APAProjectComponent, APA.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' in Assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable. 
  Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

 Exception Details: System.Runtime.Serialization.SerializationException: Type 'System.Linq.Expressions.Expression`1[[System.Func`2[[APA.Model.Models.APAProjectComponent, APA.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' in Assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

任何人都可以帮助我如何为getter撰写适当的setterOptionalPredicate,以便使用ViewState来保存lamda exression,而不是SetOptionalPredicate更改属性的接口和{{1}}方法?

提前致谢

2 个答案:

答案 0 :(得分:-1)

你不能。

您需要更改方法以定义SetOptionalPredicate被调用的条件,并在ViewState中存储条件的表示。

如果调用的lambda表达式更复杂,您可以定义一个类SetOptionalPredicateBuilder,它仅根据输入值构建SetOptionalPredicate参数。

然后ViewState将存储所有这些输入值。表单(或用户控件)使用ViewState中包含的值调用构建器。

答案 1 :(得分:-1)

我终于找到了解决方法,我将与任何可能遇到同样问题的人分享。 我安装了包linq serializer

并使用该库我重写了OptionalPredicate的getter和setter,如下所示,serialized谓词,然后将其保存到viewstate中,deserialized将它从viewstate中检索后:

private dynamic OptionalPredicate
        {
            get
            {
                if (this.ViewState[this.ClientID + "OptionalPredicate"] != null)
                {
                    var expressionSerializer = new Serialize.Linq.Serializers.ExpressionSerializer(new Serialize.Linq.Serializers.XmlSerializer());
                    return expressionSerializer.DeserializeText(this.ViewState[this.ClientID + "OptionalPredicate"].ToString()) as dynamic;   
                }
                else
                {
                    return default(dynamic);
                }
            }
            set
            {
                var expressionSerializer = new Serialize.Linq.Serializers.ExpressionSerializer(new Serialize.Linq.Serializers.XmlSerializer());
                this.ViewState[this.ClientID + "OptionalPredicate"] = expressionSerializer.SerializeText(value);
            }
        }

一切正常:)