【问题标题】:Form Elements in ASP.NET Master Pages and Content PagesASP.NET 母版页和内容页中的表单元素
【发布时间】:2010-09-15 18:10:27
【问题描述】:

好的,我当前项目的另一个障碍。

我的主页面和内容页面中都没有表单元素,我倾向于在内容中包含所有相关的表单。

然而,在当前的项目中,我们有一个他们想要两者都需要的页面。 右上角的登录表单和内容中的问题表单。

在尝试解决这个问题后,我遇到了 ASP.NET 抱怨母版页中需要单个表单元素的问题。 TBH,我真的不明白为什么这是 ASP.NET 的要求,但是嘿嘿。

有谁知道我是否/如何让主页面和内容页面包含独立工作的表单元素?

如果没有,您能否就如何继续获得所需的外观/功能提供建议?

【问题讨论】:

  • 您能否添加代码或缩减示例?我认为您在内容页面和母版页中都声明了 [form id="form1" runat="server"] 是否正确?
  • 您是否仅限于登录表单上的提交操作?不能使用用户控件登录吗?
  • Rob,你的假设是正确的。 ProfK 我们遇到的问题是,当用户在内容表单中按下回车键时,正在提交登录表单。感谢大家的帮助! :)
  • 玩了一段时间后自己找到了答案。希望对其他人有所帮助,如果不清楚,请大声疾呼。

标签: asp.net forms webforms master-pages


【解决方案1】:

我想我会回顾一下我的一些悬而未决的问题,看看我是否可以关闭其中一些。

这个很有趣。我完全不相信在 ASP.NET 页面上只能有一个表单。这对我来说毫无意义。我已经看到很多网页在网页上具有多个表单,为什么 ASP.NET 页面应该有所不同?

所以,我开始思考了。

为什么 ASP.NET 页面需要一个表单元素?

ASP.NET 页面尝试通过 PostBack 模型提供状态持久性来模拟 WinForms 环境。这为无状态环境提供了状态元素。为了做到这一点,运行时需要能够在每个“表单”中保持这种状态。它通过将数据回发给自己来做到这一点。需要注意的是:

  • PostBack 并没有什么花哨的地方。
  • 它使用 HTTP 表单和 POST,与任何其他表单相同,来自任何其他堆栈。
  • 只是因为它看起来像是在做一些特别的事情,其实不然.

那为什么只有一个?

这对我来说是百万英镑的问题(我是英国人)。我知道 ASP.NET 需要这个,尤其是在您使用 ASP.NET 服务器控件的情况下,但是为什么我不能自己制作额外的表单?

所以,我想搞砸了,只是制作你自己的表格!

我做到了。我添加了一个沼泽标准的简单表单,提交操作为“#”。然后,这会对当前页面执行 POST,其中包含请求中给定表单的表单数据。

你猜怎么着?这一切都很好。所以我最终得到了:

  • 一个母版页,其中包含一个 HTML 表单
  • 此表单回发到当前页面(基本上是使用母版的页面)。
  • 在主控的 Page_Load 代码隐藏中,我添加了代码来检查请求以查看请求中传递了哪些数据。如果它包含数据(比如隐藏字段),那么我知道帖子来自母版页上的表单,如果不是,那么它很可能是来自内容的 PostBack,可以忽略。
  • 然后我用<form runat="server" id="aspNetForm"...> </form> 标签包围了内容标签。这意味着所有内容页面都会自动拥有一个可以使用的表单。

这为我的问题提供了一个相对简单、干净的解决方案。我的登录表单可以与创建的所有内容表单一起正常工作,其中一些是复杂表单,另一些使用大量服务器控件和许多 PostBacks,等等。

我希望这对其他人有所帮助。

【讨论】:

    【解决方案2】:

    表单标签本身位于 MasterPage 中,因此,您可以将任何 asp.net 服务器控件编码到您希望的母版页上。您可以在母版页的代码隐藏文件中为这些服务器控件编写处理逻辑。

    因此,在您的示例中,您可以将登录控件放在母版页的右上角,然后将身份验证逻辑放在母版页的代码页中,而不是您的内容页。

    这允许您在每个页面上都有登录控件,并维护该处理,以及维护内容控件及其在各个页面上的处理。

    【讨论】:

    • 那么您是否建议将整个页面包装在
      中?当然它会解决问题,但是,这不是一个坏习惯吗?
    • 不在 ASP.Net Webforms 中。标准行为是将整个页面包装在一个表单元素中。
    【解决方案3】:

    其他人已经提到在给定的 ASP.NET 页面中只能有一个表单元素,并且它将包含在母版页中。到目前为止,一切都很好。但我不认为这可以帮助你完全达到你想去的地方......

    在您的母版页中,您(我假设!)定义了asp:ContentPlaceHolder 控件。您使用主页面的页面将具有相应的asp:Content 标签。你所有的页面内容都必须放在这些对应的asp:Content标签中。

    一旦进入该标记,它们就成为母版页表单的一部分。母版页可以响应来自其自己的控件的事件,而页面本身则响应来自其自己的控件的事件,您已经准备就绪。

    如果您需要页面与母版页交互,您可以通过Page.Master 属性访问它。要与母版页中的任何公开可见的代码(方法、属性等)进行交互,您需要将此属性转换为正确的类型,然后从那里访问公开可见的代码。

    在这种情况下,这应该可以帮助您到达需要的位置。 (它在多个网站上都对我有用!)

    【讨论】:

      【解决方案4】:

      罗伯,

      有趣的解决方案。我看不出你在做什么有任何问题。然而,有些人可能会遇到的问题是,如果他们尝试使用 2 个服务器表单来执行此操作。 ASP.NET 中没有规定一个页面上不能有超过 1 个 HTML 表单,只是页面上不能有多个“runat='server'”表单。显然,您已经找到了一种非常简单的方法来满足您的需求。

      我发现在大多数情况下处理单个表单不是问题,因为 ASP.NET 框架基本上用命名容器为我们分离了所有内容。但是在您最初的帖子评论中,您遇到了一个重要因素,该因素缺席但对原始问题的本质至关重要:输入关键行为。这总是会给工作带来麻烦。

      如果您要使用标准的“无所不包”服务器表单,您不能使用文本框文本更改事件来捕获正确的操作吗?当然,如果用户在按 Enter 之前更改了这两个值,你会得到奇怪的行为。而且我认为 Enter 键的核心问题是,一旦您在 HTML 表单上提交了多个提交输入,在文本框中按 ENTER 将无济于事。只有当只有一个 INPUT 元素时,回车键才会导致“点击”。

      【讨论】:

      • 嘿彼得,你是对的,输入键行为可能是“有趣的”:D 对于我的特殊问题,一切正常,因为表单的默认提交键将始终在 Enter 上“按下” .这似乎总是在生成的表单上正常工作,因此没有进一步调查。
      • 我应该补充一点,这两种形式(登录,主要内容)设计简单。登录 (HTML) 只有一个提交按钮,而内容 (ASP.NET) 可以通过属性轻松设置其默认操作。
      【解决方案5】:

      之前的答案都没有给出代码示例。以下是 Visual Studio 2012 Site.Master 的简化版本,说明了如何执行此操作:

      <%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site - Copy.Master.cs" Inherits="WebApplication1.Site1Master" %>
      <!DOCTYPE html>
      <html>
          <head runat="server">
              <title>This is a title</title>
              <asp:ContentPlaceHolder runat="server" ID="HeadContent" />
          </head>
          <body>
          <form runat="server">
          <header>
              <div class="content-wrapper">
                  <div class="float-right">
                      <section id="login">
                          <asp:LoginView runat="server" ViewStateMode="Disabled">
                              <AnonymousTemplate>
                                   <asp:ContentPlaceHolder runat="server" ID="AnonContent" />
                              </AnonymousTemplate>
                              <LoggedInTemplate>
                                  <asp:ContentPlaceHolder runat="server" ID="LoggedInContent" />
                              </LoggedInTemplate>
                          </asp:LoginView>
                      </section>
                  </div>
              </div>
          </header>
              <div id="body">
              <asp:ContentPlaceHolder runat="server" ID="FeaturedContent" />
              <section class="content-wrapper main-content clear-fix">
                  <asp:ContentPlaceHolder runat="server" ID="MainContent" />
              </section>
          </div>
          </form>
      </body>
      </html>
      

      因此,您将所有内容都包含在单个表单元素中,因此您可以在母版页中放置控件,而您的内容页面也可以使用控件。

      【讨论】:

        【解决方案6】:

        在 ASP.NET 页面上只能有一个表单。处理此问题的一种方法是在母版页的登录按钮上放置一个事件处理程序。处理程序将验证用户并在成功时重定向到同一页面(以正确运行 Page_Load 处理程序,该处理程序在事件处理程序之前运行)。

        【讨论】:

          【解决方案7】:

          我通过在母版页中嵌入 iframe 解决了当前项目中的“单击登录子表单中的返回键导致主表单提交”的问题。 iframe 指向对用户进行身份验证的 login.aspx 页面。

          <iframe id="login" src="login.aspx" frameborder="0" enableviewstate="false" scrolling="no" runat="server"></iframe>
          

          (出于某种原因,我需要关闭 /iframe 标记,否则设计视图会混淆)

          【讨论】:

            【解决方案8】:

            您可以通过以下方式从 aspx 表单访问 MasterPage 控件: 将贬损标签添加到 aspx 表单 并在后面的代码中使用 Master.FindControl(); 通过 ID 获取控件

            例如,如果您想获得 控制表单 = Master.FindControl("form")

            现在您可以在代码中使用母版页的表单了。

            希望对你有所帮助。

            【讨论】:

              【解决方案9】:

              救命!在类似的帖子中,我发布了一个可能对您有所帮助的答案。您可以使用 jquery 将内容添加到空 div。该内容可以包括表单标签,甚至是独立于服务器端代码所做的任何事情的提交函数。唯一的缺点是如果用户没有启用 javascript!

              这里不是重新发布相同的答案(以及代码),而是链接:

              Jquery Ajax loading form on asp.net webform

              【讨论】:

                【解决方案10】:

                这是 ASP.NET 的限制

                ASP.NET 设计为每页有一个表单,并且只有一个表单。当它最初设计时,这不是问题。

                然而,从那时起,这已被确定为可访问性的一个巨大问题。

                Microsoft 对此的修复是 ASP.NET MVC,如果可以的话,我建议考虑迁移到 ASP.NET MVC,因为它解决了 ASP.NET 的大量问题

                【讨论】:

                  【解决方案11】:

                  您可以拥有超过 1 个表单。 (一次只有 1 个可见)代码行 1 = 表格 1 可见 / 表格 2 隐藏。代码 2 表 2 可见/表 1 隐藏。 = 已解决(这也适用于静态联系表单

                  【讨论】:

                  • 这不能很好地处理所需的功能。整个问题是基于有 2 个可以同时工作的表单的要求。
                  【解决方案12】:

                  不,每页只能有一个 asp.net 表单。 这是自 1.0 以来的规则

                  它们应该共享相同的表单

                  【讨论】:

                  • 这是不正确的。您只能拥有一种带有 runat="server" 的表单,而不是一种形式。请记住,在所有程序化的东西的最后,它仍然只是一个网页:)
                  • 当您在母版页中有由表单包裹的 contentplaceholder 时,如果进入 cpholder 的其他页面在其中有一个表单,则当它作为 html 提供给最终用户时,表单标签将被删除。这就是我现在所经历的
                  猜你喜欢
                  • 2013-02-08
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-02-02
                  • 2021-08-07
                  • 2015-06-28
                  • 2013-02-12
                  • 2011-07-19
                  相关资源
                  最近更新 更多