UpdatePanel 内 FormView 中的 FileUpload

发布于 2024-09-15 17:53:41 字数 1520 浏览 11 评论 0原文

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

现在,这个 FormView 还包含 4 个 FileUpload 控件,您可能知道这些 fileupload 控件需要完整的回发,因为大多数浏览器不允许 Javascript 访问磁盘。因此,这个问题可以通过执行以下操作来解决:

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

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

问题:
由于 InsertButtonUpdateButton 驻留在 Formview 内,因此我无法通过标记直接访问它们的 ID。 MSDN

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

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

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

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

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

The Scenario:
I have an ASP.Net webpage which I intend to use for letting the user(not the real users, but content manager basically) insert and edit the records in a table using a FormView. This FormView is inside an UpdatePanel, as I'm also using cascading dropdownlists to let the user select some values.

Now, this FormView also contains 4 FileUpload controls, and as you might know that these fileupload controls require a full postback since most browsers do not let Javascript access the disk. So, this problem would have been solved by doing something like:

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

Edit: Forgot to add that the fileuploading takes place in the OnUpdating and OnInserting events of the SqlDataSource.

The Problem:
Since the InsertButton and the UpdateButton reside inside the Formview, I cannot directly access their ID's through markup. And MSDN says that:

Programmatically adding
PostBackTrigger controls is not
supported.

Please suggest some solution to make this work. Any insight on the matter is highly appreciated. Thanks.

P.S.- A workable solution for me was to set the UpdatePanel's PostBackTrigger as the whole FormView itself:

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

But now due to a bit of change in requirements, this solution(if you call it a solution) is not acceptable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

§对你不离不弃 2024-09-22 17:53:41

您是否考虑过使用 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);

        }

这只是一些代码,只是为了让您弄清楚您是否对这种处理上传的方式感兴趣,如果您想要的话,我可以给您更多。

再见,祝你的代码好运,

Have you given a though about using Iframe for doing the postback ? something like:

<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>

with uploaderSender.aspx like :

<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>

and UploaderReceiver.aspx like :

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);

        }

this is just bits of code just for you to figure out if you would be interested in this way of dealing with the upload, I can give you more if you want after.

see you, and good luck with your code,

[旋木] 2024-09-22 17:53:41

耶!!终于开始工作了!

方法如下:

与 MSDN 所说的相反,我们实际上可以通过编程方式添加回发触发器。不一定是 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>

CodeBehind:

//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 =“始终”

Yay!! Finally got it to work!

Here's How:

Well contrary to what MSDN says, we can in fact add PostBack Triggers Programmatically. Not necessarily to the UpdatePanel, but to the ScriptManager.

After hours of playing around, here's what worked:

We are not able to access controls inside a FormView, untill the template has been rendered, so we can only add postback triggers after the formview's OnDataBound Event.

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.
    }

And now, if your UpdatePanel causes ConditionalUpdate, you can do something like this to make it work:

The Markup:

<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>

CodeBehind:

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

Otherwise, if your situation allows it(as mine does), just set the UpdatePanel's UpdateMode="Always"

书间行客 2024-09-22 17:53:41

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

您将您的问题表述为:

由于 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>

This is old, but was trying to solve another problem and ran into this. This wasn't my problem, but here's an alternative for anyone new who runs into this as well.

You stated your problem as:

Since the InsertButton and the UpdateButton reside inside the Formview, I cannot directly access their ID's through markup

You actually can access their ID's through markup to use as the ControlID in the PostBackTrigger. You just have to use the button's name that is created in the page html mark-up as the ControlID. You can find the name created by viewing the page source when you're viewing the page in the browser. It typically is the name of the FormView + $ + name of the button.

For example, let's say you have a FormView named "FormView1" that contains an Insert button which you gave the ID of "btnInsert" during design. If you open up your page in the browser to view it live and then view the page's source, you'll notice that the html mark-up of the button will actually be given the name "FormView1$btnInsert".

Use that name as the ControlID in your PostBackTrigger and your update panel will work.

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
       <Triggers>
             <asp:PostBackTrigger ControlID="FormView1$btnInsert" />
       </Triggers>
       <ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文