0
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"]]

所以你 - 它来自会话变量。使用断点我可以看到附件列表被填充得很好,但是当涉及到点击事件处理程序时它是空的!?不为空,只是计数 == 0。

4

1 回答 1

2

它变成空的,因为它没有存储在 ViewState 中(我在这里从方法名称中假设 asp.net webforms)。

请参阅如何:在视图状态中保存值ASP.NET 页面生命周期概述

或者将值存储在会话中,请参阅如何:在会话状态中保存值

EDIT2:有了额外的信息 - 我之前遇到过这个问题,已经通过将代码移出 Page_load 并进入辅助方法(更好)并在事件回调中使用它来解决。我最初确实声明事件回调是在 Page_Load 之前发生的 - 但是我刚刚检查过这个,它没有,但是我确定我过去遇到过问题,在某些情况下,有孩子控件,Page_Load 未完成 - 可能与验证有关。

无论如何,它可能应该按照以下几行重新编码 - 以消除 Page_load 和附件之间的依赖关系。使用 IENumerables(而不是列表)也可以很简洁 - 请参阅最后一个示例。

例如

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());
}
于 2011-11-14T15:30:15.280 回答