上次說到(和Atlas專家探討Atlas的一些Bug和疑問),在Atlas裡面使用FileUpload上傳附件有困難:UpdatePanel每次回傳的只是一個XmlHttp的請求和ViewState,並沒有回傳整個頁面,所以,在server端無法獲得FileUpload的檔案。
首先想到的解決方案就是不使用UpdatePanel:彈出一個新視窗,上傳檔案。新視窗裡面不使用UpdatePanel。 這個方法當然可以。
今天忽然想起來,GMail裡面的附件上傳:後台上傳檔案,還不影響你前邊郵件的編輯,也不整體頁面重新整理。這個模式夠帥!不用開啟新視窗,一個頁面搞定,頁面也不用重新整理。
對比了一下,好象第二種方法更好一點。於是FireBug(AJAX程式的跟蹤工具:fireBug0.4)了一下GMail,發現了裡面的處理是這樣的<iframe scrolling="auto" frameborder="0" onload="try{if(top.js.init)top.js._IF_OnLoaded('v1')<input type="file" onchange="top.js._CM_OnAttach(window,this)" name="f_ephki04a" size="50"/>
他的上傳附件是放在一個iframe 裡面的,然後控制項的onchange事件裡面有些處理。
果然是個不錯的方法。
於是我做了這樣的處理方案:
1:首頁面中使用UpdatePanel,然後UpdatePanel裡面放置的不是FileUpload控制項,而是一個Iframe
2:這個iframe在連結一個新的頁面,那個頁面裡面有FileUpload控制項。
3:上傳完畢後,告訴首頁面上傳得結果
先看一個直接使用FileUpload的例子:這個例子裡面,服務端是無法找到上傳檔案的。 <atlas:UpdatePanel ID="up1" Mode="Conditional" runat="server">
<ContentTemplate>
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</ContentTemplate>
</atlas:UpdatePanel>
看看,我們該如何?
1:建立首頁面Default.aspx
在適當的位置,放置一個上傳附件的UpdatePanel地區
<atlas:UpdatePanel ID="up_attachment" Mode="Conditional" runat="server">
<ContentTemplate>
<iframe id="file" name="file" src="attachment.aspx"></iframe>
</ContentTemplate>
</atlas:UpdatePanel>
2:建立上傳檔案的頁面attachment.aspx,然後放上FileUpload控制項<div>
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="OK" OnClick="Button1_Click" />
</div>
3:在attachment.aspx裡面,上傳檔案之後調用首頁面的js,報告上傳情況。這是函數原型: <script>
window.top.callBack(fileName);
</script>
4:Default.aspx首頁面裡面增加這個函數,處理傳回值
<script>
function callBack(fileName)
{
document.getElementById('Attach1').innerHTML=fileName;
}
</script>
然後,搞定。
這個方案,雖然還是兩個頁面,但是看起來處理都在一個頁面裡面,頁面處理無重新整理。