אם יצא לכם לכתוב פקד המאפשר להעלות קבצים לשרת, שומר אותם ב - Session ומתי שהוא תנסו לקרוא את התוכן של הקבצים, ייתכן שתקבלו את השגיאה:
Cannot access a closed file.
בפוסט זה אני אדגים כתיבה של פקד כזה (פקד פשוט מאוד - עבור הדוגמא) וכיצד לפתור את הבעייה.
נכתוב דף בשם uploader.aspx,
קוד ה - html:
<form id="form1" runat="server">
<div>
<asp:FileUpload runat="server" ID="fu1" />
<asp:Button Text="Upload" OnClick="upl_click" runat="server" />
</div>
</form>
קוד צד שרת:
protected void upl_click(object sender, EventArgs e)
{
List<HttpPostedFile> list = (List<HttpPostedFile>)Session["files"];
if (list == null)
{
list = new List<HttpPostedFile>();
Session["files"] = list;
}
list.Add(Request.Files[0]);
Response.Write("<script>parent.uploaded('" + Request.Files[0].FileName + "')</script>");
}
ראשית נקבל את המקום שבו אנחנו שומרים את כל הקבצים (אם לא קיים נייצר אותו).
לאחר מכן נוסיף את הקובץ החדש,
ובסוף נריץ סקריפט שיפעיל פונקצייה בדף שמארח את הפקד. (ושוב אני אדגיש - זהו קוד בסיסי ופשוט ביותר - רק כדי להראות כיצד להתגבר על התקלה)
נניח שיש לנו דף המכיל את הפקד (נשתמש ב - colorbox כדי להציג אותו בצורה טובה יותר)
קוד ה - html:
בהתחלה נוסיף את קבצי הסקריפט והעיצוב הנדרשים:
<script src="jquery-1.6.4.js" type="text/javascript"></script>
<script src="jquery.colorbox.js" type="text/javascript"></script>
<link href="colorbox.css" rel="stylesheet" type="text/css" />
כעת נכתוב את ה - html הבא:
<form id="form1" runat="server">
<div>
Files:
<ul>
</ul>
<asp:Button Text="Save" OnClick="save_click" runat="server" />
<input type="button" value="Add File" onclick="addFile()" />
</div>
</form>
בזמן לחיצה על Add File נפעיל את הסקריפט הבא:
function addFile() {
var a = $(document.createElement('a'));
a.attr('href', 'uploader.aspx');
a.colorbox(
{
iframe: true,
opacity: '0.55',
height: '200',
width: "400",
open: true
});
}
הסקריפט יודע לייבא את התוכן של דף uploader כ - iframe ולהציג את החלון.
כשהמשתמש ילחץ על הלחצן "Upload" בדיאלוג שייפתח לו, אמור לרוץ פונקציה בשם uploaded (כפי שראינו בקוד צד שרת של uploader)
function uploaded(fileName) {
var li = document.createElement('li');
li.appendChild(document.createTextNode(fileName));
document.getElementsByTagName('ul')[0].appendChild(li);
$.colorbox.close();
}
כעת בלחיצה על Save ננסה להריץ את הקוד הבא:
protected void save_click(object sender, EventArgs e)
{
List<HttpPostedFile> list = (List<HttpPostedFile>)Session["files"];
foreach (var item in list)
{
byte[] data = new byte[item.InputStream.Length];
item.InputStream.Read(data, 0, data.Length);
}
}
כאן נקבל את השגיאה של Cannot access a closed file.
לאחר קצת שיטוט בגוגל הגעתי
לכאן, תוכלו לקרוא על ההבדלים בניהול הזכירון בין גרסאות 1.1 ומעלה, מבחינתנו המשמעות היא שקבצים מעל גודל מסויים לא נשמרים בזיכרון וכדי לפתור את זה נוכל להוסיף את השורה הבאה לקונפיג.
<httpRuntime maxRequestLength="10240" requestLengthDiskThreshold="4096" />
כמובן שאת הערכים תשנו לפי הצורך.
משמעות הפרמטר הראשון, היא מה גודל הקבצים המקסימלית לשליחה לשרת, משמעות הפרמטר השני היא מה הגודל של מידע שנשמר בזיכרון, מידע שעובר את הגודל הזה, נשמר בזיכרון זמני. (הערך שלו לא יכול להיות גדול יותר מהערך של הפרמטר הראשון)