在 aWebControl
中,我有一个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 是一个DataSource
,我创建这个属性是因为我想有可能轻松过滤数据,例如:
//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,它会引发异常。
有没有方便的解决方案来解决这个问题?由于显而易见的原因,我无法将使用数据源的所有网页标记为 [可序列化]。
编辑1:我不明白的东西。如果我将 存储Dictionary
在Session
对象中(使用BinaryFormatter
vs LosFormatter
for 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;
}