2007年12月23日

在UpdatePanel下,使用FileUpload控制項

我想這個問題一值是很多人很頭痛的問題,常常會有人問,我在UpdatePanel下使用FileUpload怎麼沒有辦法抓到它的檔案呢?

在微軟的官方討論區,也有這樣的一篇文章,說明了,....就是不能用:http://forums.microsoft.com/MSDN-CHT/ShowPost.aspx?PostID=1319366&SiteID=14

不過山不轉,路轉摟~~我們改變一下做法,利用IFrame來做做看~~應該也是不錯的選擇唷~~
否則要因為使用FileUpload而捨去UpdatePanel,那我可是無法接受的啦!

設計理念:撰寫一個上傳附件的UserControl。然後在UserControl裡面擺放一個IFrame,而這個IFrame裡面指向的網頁裡面,再綁放一個FileUpload控制項,也就是說在IFrame內(沒有UpdatePanel),做上傳的功能,然後再將相關資訊利用JavaScript回傳給Parent的頁面裡,進行呈現的作動!

檔案:ucUploadFile.ascx(User Control) 、 ucUploadFile.aspx(IFrame裡面的Page)

ucUploadFile.ascx

<%@ Control Language="VB" AutoEventWireup="false"
CodeFile="ucUploadFile.ascx.vb" Inherits="ucUploadFile" %>

<ASPExtensions:UpdatePanel runat="server" ID="UpdatePanel1"
UpdateMode="conditional">

    <ContentTemplate>

       
<table width="100%">

           
<tr>

               
<td style="white-space:nowrap;">

                   
<iframe id="UploadFrame" frameborder="0" runat="server"
width="100%"></iframe>

                   
<asp:TextBox ID="UpData" runat="server" Text=""
CssClass="Hidden"></asp:TextBox>

                   
<asp:Button ID="SynBtn" runat="server" Text="" CssClass="Hidden"
/>

               
</td>

           
</tr>

           
<tr>

               
<td>

                   
****************呈現上傳檔案內容的區塊****************

               
</td>

           
</tr>

       
</table>

    </ContentTemplate>

</ASPExtensions:UpdatePanel>


ucUploadFile.ascx.vb

Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreRender

       
'設定上傳的IFrame網址

       
Me.UploadFrame.Attributes.Add("src", "../UsrCtls/ucUploadFile.aspx?"
& _

                                            
"&ud=" & Url.UrlEncode(Me.UpData.ClientID) & _

                                            
"&sb=" & Url.UrlEncode(Me.SynBtn.ClientID))

       
Me.SynBtn.UseSubmitBehavior = False

End Sub


ucUploadFile.aspx

<%@ Page Language="VB" AutoEventWireup="false"
CodeFile="ucUploadFile.aspx.vb" Inherits="UsrCtls_ucUploadFile"
%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server"><title>Upload
File</title></head>

<body onload="__PageOnLoad(event);">

    <form id="form1"
runat="server">

       
<asp:Label ID="Label1" runat="server"
Text="路徑"></asp:Label><asp:FileUpload
ID="FileUpload1" runat="server"
CssClass="CTextBox4Col"/>&nbsp;&nbsp;<asp:Label
ID="Label2" runat="server"
Text="檔案說明"></asp:Label><asp:TextBox
ID="FileDesc" runat="server" CssClass="CTextBox4Col" MaxLength="255"
/>&nbsp;&nbsp;<asp:Button ID="Upload"
runat="server" Text="上傳" SkinID="UploadButton"/>

    </form>

</body>

</html>


ucUploadFile.aspx.vb

    Protected Sub Upload_Click(ByVal sender
As Object, ByVal e As System.EventArgs) Handles Upload.Click

       
Try

           
'請確認選擇之檔案是否正確!

           
If Me.FileUpload1.HasFile = False Then

               
'Do Error Control

               
Exit Sub

           
End If



           
'進行存檔

           
Me.FileUpload1.SaveAs("***********路徑**************")



           
dim strReturn as string = "****************************************"

           
Me.Page.ClientScript.RegisterStartupScript(Me.GetType, "SynData",
"parent.document.getElementById('" & Me.UpDataClientId
& "').value = '" & strReturn & "';var
userAgent = navigator.userAgent; if(userAgent.indexOf('Firefox') !=
-1){ $(parent.document.getElementById('" & Me.SynBtnClientId
& "')).click(); }else{ parent.document.getElementById('"
& Me.SynBtnClientId & "').click(); }", True)



           
Me.FileDesc.Text = ""

       
Catch ex As Exception

            'Do
Error Control

           
Throw

       
End Try

    End Sub


這邊只是大至上將整個設計理念,呈現出來而已,有些比較細節的東西,可能你要自己調整,例如我指定給IFrame的網址有參數,然後要怎麼將參數接下來,那應該不用我說了吧!
另外要回傳哪些資訊回去,就看你自己的決定摟~~
而回傳回去,要做甚麼事情,也是你要自己決定吧!

有問題再提出來討論吧!

3 則留言:

  1. 書裡有提到,將
    asp:AsyncPostBackTrigger ControlID="UploadButton" EventName="Click"
    改成
    asp:PostBackTrigger ControlID="UploadButton"

    ,不過還是會引發整個頁面的Postback..

    回覆刪除
  2. AsyncPostBackTrigger跟PostBackTrigger是不一樣的唷~~
    Async是指非同步的意思,而你如果設定PostBackTrigger那就代表整各頁面會PostBack阿~~
    它的用途不一樣,舉例來說,如果我們在一個UpdatePanel裡面擺放了兩個Button,
    Button1 Click Event只會更新該UpdatePanel裡面的資料,那它就設定給AsyncPostBackTrigger

    另外如果Button2 Click Event要更新UpdatePanel外面的資料的話,而且是在Server端去更新,那就必須要整各頁面PostBack,那此時就將Button2設定給PostBackTrigger摟~~

    兩個是不同的東西,所以瞜~~不要搞混了

    回覆刪除
  3. A..

    我的意思是說,
    為了解決在UpdatePanel使用FileUpload時,無法順利上傳檔案的問題,是將AsyncPostBackTrigger改為PostBackTrigger,引發整個網頁的回傳,就可以解決無法上傳的問題..

    回覆刪除