ASP.NET母版页和内容页中的表单元素

时间:2008-10-07 13:19:39

标签: asp.net forms webforms master-pages

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

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

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

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

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

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

12 个答案:

答案 0 :(得分: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>标记包围了内容标记。这意味着所有内容页面都自动拥有可以使用的表单。

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

我希望这有助于其他人。

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:4)

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

在您的母版页中,您(我假设!)定义了asp:ContentPlaceHolder个控件。然后,使用母版的页面会有相应的asp:Content标记。您的所有网页内容都必须包含相应的asp:Content代码。

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

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

这应该可以让您在这种情况下获得所需的位置。 (它在多个网站上对我有用!)

答案 3 :(得分:4)

罗布,

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

我发现在大多数情况下处理单个表单不是问题,因为ASP.NET框架基本上将命名容器与我们分开。但是在你最初的评论中,你找到了一个重要的因素,这个因素对原始问题的本质至关重要:输入关键行为。这总是会让猴子扳手投入工作。

如果您使用标准的“全包”服务器表单,您是否无法使用文本框文本更改事件捕获正确的操作?当然,如果用户在点击输入之前改变了两个值,你会得到奇怪的行为。我认为enter键的核心问题是,一旦你在HTML表单上有多个提交输入,在文本框中点击ENTER就不会做任何事情。只有当存在单个INPUT元素时,输入键才会导致“单击”。

答案 4 :(得分: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>

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

答案 5 :(得分:2)

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

答案 6 :(得分:0)

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

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

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

答案 7 :(得分:0)

您可以通过以下方式从aspx表单访问MasterPage控件: 将detractive标签添加到aspx表单&lt;%@ MasterType VirtualPath =“〜/ Site.Master%&gt; 并在后面的代码中使用 Master.FindControl(); 来获取ID控件

例如,如果你想获得  控制表格= Master.FindControl(“表格”)

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

我希望这有帮助。

答案 8 :(得分:0)

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

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

Jquery Ajax loading form on asp.net webform

答案 9 :(得分:0)

这是ASP.NET的限制

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

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

Microsoft Fix for this是ASP.NET MVC,如果你能够建议考虑转移到ASP.NET MVC,因为它解决了ASP.NET的大量问题

答案 10 :(得分:-2)

您可以拥有多个表单。 (一次只能看到1个)代码行1 =形式1可见/形式2隐藏。代码2表格2可见/表格1隐藏。 =已解决(这对静态联系表格也很好

答案 11 :(得分:-3)

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

他们应该共享相同的表格