【问题标题】:FileUpload in FormView inside an UpdatePanel在 UpdatePanel 内的 FormView 中的 FileUpload
【发布时间】:2011-04-03 02:59:45
【问题描述】:

情景:
我有一个 ASP.Net 网页,我打算使用它让用户(不是真正的用户,而是基本上是内容管理器)使用 FormView 在表中插入和编辑记录。此 FormView 位于 UpdatePanel 内,因为我还使用级联下拉列表让用户选择一些值。

现在,这个 FormView 还包含 4 个 FileUpload 控件,并且您可能知道这些文件上传控件需要完整的回发,因为大多数浏览器不允许 Javascript 访问磁盘。所以,这个问题可以通过以下方式解决:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <Triggers>
           <asp:PostBackTrigger ControlID="InsertButton" />
           <asp:PostBackTrigger ControlID="UpdateButton" />
           </Triggers>
                    <ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>

编辑:忘记添加文件上传发生在 SqlDataSource 的 OnUpdatingOnInserting 事件中。

问题:
由于InsertButtonUpdateButton 位于Formview 中,因此我无法通过标记直接访问它们的ID。还有 MSDN says 那个:

以编程方式添加 PostBackTrigger 控件不是 支持。

请提出一些解决方案来完成这项工作。对此事的任何见解都将受到高度赞赏。谢谢。

P.S.- 对我来说可行的解决方案是将 UpdatePanel 的 PostBackTrigger 设置为整个 FormView 本身:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <Triggers>
           <asp:PostBackTrigger ControlID="FormView1" />
           </Triggers>
                    <ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>

但是现在由于需求的一些变化,这个解决方案(如果你称之为解决方案)是不能接受的。

【问题讨论】:

    标签: asp.net file-upload updatepanel postback formview


    【解决方案1】:

    您是否考虑过使用 Iframe 进行回发?类似:

    <iframe name="uploader" id=uploader 
              src="uploaderSender.aspx?AllowedExtension=<%= AllowedExtension %>&StoringPath=<%= StoringPath %>&StoringFileName=<%= StoringFileName %>&OldFileName=<%= OldFileName %>&MaximumSize=<%= MaximumSize %>"
             width="450" height="50" frameborder=0  scrolling=no >
            </iframe>
    

    与 uploaderSender.aspx 类似:

    <form action="UploaderReceiver.aspx" method="post"  enctype="multipart/form-data">
     <input type="file" name="file" id="file"  onchange="document.getElementById('IsFileUploading').style.visibility = 'visible'; document.forms[0].submit()"/>
    
        <span id="IsFileUploading" style="visibility: hidden">
            <asp:Image ID="Image1" runat="server" ImageUrl="~/immagini/Ajax-loader.gif" />
        </span>
    </form>
    

    和 UploaderReceiver.aspx 类似:

    protected void Page_Load(object sender, EventArgs e)
            {
    
                //if there is one file to process
                if (Request.Files.Count > 0)
                    //create the folder if it does'nt exists and returns the local path to get it
                    string StoringPathToBeSaved = StoringPath.GetFolderPath();
    
                    // append the name of the file to upload to the path.
                                StoringPathToBeSaved = StoringPathToBeSaved + StoringFileName + Extension;
    
                                Request.Files[0].SaveAs(StoringPathToBeSaved);
    
            }
    

    这只是一些代码,仅供您了解您是否对这种处理上传的方式感兴趣,如果您愿意,我可以给您更多。

    再见,祝你的代码好运,

    【讨论】:

    • 感谢您的意见先生,但实际上我目前是 ASP.Net 本身的初学者,并且对 IFrame 没有一点想法,虽然它会像您说的那样工作,但是恐怕现在我只需要在几个小时内完成手头的这项任务(以及其他一些任务),我想我需要一些时间来学习 IFrame 并将它们实施到我的项目中。无论如何,感谢您的帮助。 +1 给你 :)
    【解决方案2】:

    耶!!终于搞定了!

    方法如下:

    与 MSDN 所说的相反,我们实际上可以通过编程方式添加 PostBack 触发器。不一定是UpdatePanel,而是ScriptManager

    玩了几个小时后,这就是有效的方法:

    在模板渲染之前,我们无法访问 FormView 中的控件,因此我们只能在 formview 的 OnDataBound 事件之后添加回发触发器。

    protected void FormView1_DataBound(object sender, EventArgs e)
        {
            if (FormView1.CurrentMode == FormViewMode.Edit)
            {
                LinkButton lb = (LinkButton)FormView1.FindControl("UpdateButton");
                ScriptManager.GetCurrent(Page).RegisterPostBackControl(lb);
            }
    
            //Similarily you can put register the Insert LinkButton as well.
        }
    

    现在,如果您的 UpdatePanel 导致 ConditionalUpdate,您可以执行以下操作以使其正常工作:

    标记:

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
               <ContentTemplate>..
                <EditItemTemplate>
                  ...
                <asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" OnClick="Cause_PostBack"CommandName="Update">Update</asp:LinkButton>
                 ...
                </EditItemTemplate>
               ..</ContentTemplate>
    </asp:UpdatePanel>
    

    代码隐藏:

    //call this function as the OnClick Event Handler for the Controls you want to register as
    //triggers.
    protected void Cause_PostBack()
        {
            UpdatePanel1.Update();
        }
    

    否则,如果您的情况允许(如我的情况),只需设置 UpdatePanel 的 UpdateMode="Always"

    【讨论】:

      【解决方案3】:

      这是旧的,但试图解决另一个问题并遇到了这个问题。这不是我的问题,但对于遇到此问题的任何新人来说,这都是一个替代方案。

      您将问题表述为:

      由于 InsertButton 和 UpdateButton 位于 Formview 中,我无法通过标记直接访问它们的 ID

      您实际上可以通过标记访问他们的 ID,以用作 PostBackTrigger 中的 ControlID。您只需使用在页面 html 标记中创建的按钮的 name 作为 ControlID。当您在浏览器中查看页面时,您可以找到通过查看页面源创建的名称。它通常是 FormView 的名称 + $ + 按钮的名称。

      例如,假设您有一个名为“FormView1”的 FormView,其中包含一个插入按钮,您在设计期间提供了“btnInsert”的 ID。如果您在浏览器中打开页面进行实时查看,然后查看页面的源代码,您会注意到按钮的 html 标记实际上将被命名为“FormView1$btnInsert”。

      使用该名称作为 PostBackTrigger 中的 ControlID,您的更新面板将起作用。

      <asp:UpdatePanel ID="UpdatePanel1" runat="server">
             <Triggers>
                   <asp:PostBackTrigger ControlID="FormView1$btnInsert" />
             </Triggers>
             <ContentTemplate>....</ContentTemplate>
      </asp:UpdatePanel>
      

      【讨论】:

        猜你喜欢
        • 2011-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-07
        相关资源
        最近更新 更多