At what point in my code did this List<> become empty?
-
28-02-2021 - |
سؤال
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());
}