namespace Messages
{
public partial class Email
{
List<Document> attachments = new List<Document>();
protected void Page_Load(object sender, EventArgs e)
{
foreach(Document document in documentList)
{
attachments.Add(document);
}
}
protected void btnSend_Click(object sender, EventArgs e)
{
sendMail(attachments);
}
}
}
正如你猜测的那样,为了解释的目的,我已经删除了这些代码,但这几乎就是我正在做的事情。我有一种感觉,它与深度/浅层复制和克隆有关,如果是这样的话 - 有人可以帮助解释这里发生了什么以及如何避免它/以不同的方式填充列表。
非常感谢,
丹
编辑:对不起,我写过'documentList',它实际上是:(List<Document>)Session[Request.QueryString["documentList"]]
所以你 - 它来自一个会话变量。使用断点我可以看到附件列表正在填充,但是当它涉及到click事件处理程序时它是空的!?不为空,只计算== 0。
答案 0 :(得分:2)
它变为空,因为它没有存储在ViewState中(我假设asp.net webforms来自方法名称)。
请参阅How to: Save Values in View State 和ASP.NET Page Life Cycle Overview
或者将值存储在会话中,请参阅How to: Save Values in Session State
EDIT2:有了额外的信息 - 我已经解决了这个问题,之前已经通过将代码从Page_load转移到辅助方法(更好)并在事件回调中使用它来解决。我原先说过事件回调是在Page_Load之前发生的 - 但是我刚刚检查了这个,但事实并非如此,但是我确信我在过去某些情况下遇到过问题,有孩子控件,Page_Load没有完成 - 可能与验证有关。
无论如何,它应该沿着以下行重新编码 - 以消除Page_load和附件之间的依赖关系。使用IENumerables(而不是列表)也可以很整洁 - 参见最后的例子。
e.g。
List<Document> getAttachments()
{
List<Document> attachments = new List<Document>();
foreach(Document document in (List<Document>)Session[Request.QueryString["documentList"]])
attachments.Add(document);
}
然后在回调中:
protected void btnSend_Click(object sender, EventArgs e)
{
sendMail(getAttachments());
}
然而也值得建议使用LINQ这样做:
IEnumerable<Document> getAttachments()
{
return ((List<Document>)Session[Request.QueryString["documentList"]]).Select(doc => doc);
}
protected void btnSend_Click(object sender, EventArgs e)
{
sendMail(getAttachments());
// or if sendMail doesn't accept IEnumerable then do :
//sendMail(getAttachments().ToList());
}