سؤال

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);
        }
    }
}

As you can guess, I've stripped this code right down for explanation purposes but that's pretty much all I'm doing with it. I've got a feeling it's to do with deep/shallow copying and cloning, if so - can someone help explain what's gone on here and how I can avoid it/populate the list differently.

Thanks a lot,

Dan

EDIT: Sorry, where I've wrote 'documentList' it actually reads:

(List<Document>)Session[Request.QueryString["documentList"]]

So yer - it's coming from a session variable. Using breakpoints I can see the attachments list is being populated just fine, but then when it comes to the click event handler it's empty!? Not null, just count == 0.

هل كانت مفيدة؟

المحلول

It becomes empty because it's not being stored in the ViewState (I'm assuming asp.net webforms here from the method names).

See How to: Save Values in View State and ASP.NET Page Life Cycle Overview

Alternatively store the value in the Session see How to: Save Values in Session State

EDIT2: with the extra info - I've had problems with this before that have been resolved by moving the code out of Page_load and into a helper method (better) and use this in the event callback. I did originally state that the event callback was coming before the Page_Load - however I've just checked this, and it doesn't, however I'm sure that I've had a problem in the past where in certain situations, with child controls, the Page_Load wasn't completing - possibly related to validation.

Anyway it should probably be recoded along the following lines - to remove the dependancy between Page_load and attachments. Using IENumerables (rather than lists) can also be neat - see the final example.

e.g.

List<Document> getAttachments()
{
    List<Document> attachments = new List<Document>();

    foreach(Document document in (List<Document>)Session[Request.QueryString["documentList"]])
            attachments.Add(document);
}

and then in the callback:

protected void btnSend_Click(object sender, EventArgs e)
{
    sendMail(getAttachments());
}

however also worth suggesting using LINQ to do it like this:

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());
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top