在一个
这个 WebControl 是一个数据源,我创建了这个属性是因为我想要轻松地过滤数据,例如:
它的表现非常出色,但是如果我将代码改为这样:
WebControl
中,我有一个名为 Filters
的属性,定义如下:public Dictionary<string, Func<T, bool>> Filters
{
get
{
Dictionary<string, Func<T, bool>> filters =
(Dictionary<string, Func<T, bool>>)ViewState["filters"];
if (filters == null)
{
filters = new Dictionary<string, Func<T, bool>>();
ViewState["filters"] = filters;
}
return filters;
}
}
这个 WebControl 是一个数据源,我创建了这个属性是因为我想要轻松地过滤数据,例如:
//in page load
DataSource.Filters.Add("userid", u => u.UserID == 8);
它的表现非常出色,但是如果我将代码改为这样:
//in page load
int userId = int.Parse(DdlUsers.SelectedValue);
DataSource.Filters.Add("userid", u => u.UserID == userId);
它不再起作用了,我得到了这个错误:
程序集“...”中的类型System.Web.UI.Page未标记为可序列化。
发生了什么:
- 序列化器检查字典。它看到其中包含一个匿名委托(lambda)
- 由于委托是在类中定义的,因此它尝试序列化整个类,在这种情况下是System.Web.UI.Page
- 该类未标记为可序列化
- 由于3的原因,它引发异常。
是否有任何方便的解决方法来解决这个问题?由于明显的原因,我无法将我使用数据源的所有网页都标记为[serializable]。
编辑1:我不理解的一些事情。如果我将Dictionary
存储在Session
对象中(使用BinaryFormatter
而不是LosFormatter
进行ViewState
),它就可以工作!我不知道这是如何可能的。也许BinaryFormatter
可以序列化任何类,即使它们不是[serializable]
?
编辑2:最小的可以重现问题的代码:
void test()
{
Test test = new Test();
string param1 = "parametertopass";
test.MyEvent += () => Console.WriteLine(param1);
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, test); //bang
}
}
[Serializable]
public class Test
{
public event Action MyEvent;
}