24

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

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

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

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

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

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

4

12 回答 12

19

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

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

所以,它让我思考。

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

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

  • PostBack 并没有什么花哨的地方。
  • 它使用来自任何其他堆栈的 HTTP 表单和 POST,与任何其他表单相同。
  • 只是因为它看起来可能在做一些特别的事情,但实际上并非如此,所发生的只是 POST 返回一些有关导致它的原因的信息,因此您可以在服务器端代码中执行诸如处理客户端事件之类的事情。

那为什么只有一个?

这对我来说是百万英镑的问题(我是英国人)。我知道 ASP.NET 需要这个,特别是如果您使用 ASP.NET 服务器控件,但为什么我不能自己制作附加表单?

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

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

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

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

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

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

于 2008-10-27T16:54:59.310 回答
5

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

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

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

于 2008-10-07T13:28:29.800 回答
4

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

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

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

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

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

于 2008-10-07T13:49:43.470 回答
4

抢,

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

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

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

于 2008-10-27T17:17:51.073 回答
3

以前的答案都没有给出代码示例。这是 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>

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

于 2013-01-12T17:24:23.370 回答
2

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

于 2008-10-07T13:26:24.860 回答
0

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

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

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

于 2008-11-20T11:12:36.577 回答
0

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

例如,如果您想获取 Control form = Master.FindControl("form")

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

我希望这会有所帮助。

于 2010-11-07T12:52:53.470 回答
0

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

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

在 asp.net webform 上的 Jquery Ajax 加载表单

于 2011-11-18T23:17:28.987 回答
0

这是 ASP.NET 的限制

ASP.NET is designed to have one form per page and only one form. When it was originally designed that was not a problem.

However since then this has been identified as a huge problem with accessibility.

Microsoft Fix for this was ASP.NET MVC, if you are able to I would suggest considering moving to ASP.NET MVC as it solves a large number of problems with ASP.NET

于 2015-09-16T12:58:05.037 回答
-2

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

于 2010-03-31T10:20:38.197 回答
-3

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

他们应该共享相同的表格

于 2008-10-07T13:21:35.057 回答