我有一个使用 ASP.NET登录控件和表单身份验证。我已将asp:LoginStatus控件放在另一个Web用户控件中,该控件管理我站点的Header部分的显示。

我遇到的问题是LoginStatus控件提供的ReturnURL引用了Header Control的路径,而不是用户当前所在的页面。这可能是由于类层次结构,并且Header Control(ascx)实际上在.aspx文件上使用Server.Execute来生成HTML。这是为了避免在页面上不允许有多个服务器端表单的问题。

因此页面的实际类层次结构如下:

Default.aspx - Uses Page.Master
Page.Master includes <foo:Header> 
    (with a reference to "~/Controls/Components/Header.ascx")
Header.ascx simply includes an <asp:Literal> 
    on Page_Load performs a Server.Execute ("~/Controls/Pages/Header.aspx") 
    and writes the content out to the Literal
Header.aspx includes <asp:LoginStatus>

当用户点击登录链接时,他们被正确地重定向到Login.aspx,但显示的ReturnURL(错误 - 虽然我能理解为什么)"ReturnUrl=%2fControls%2fPages%2fHeader.aspx"

登录页面后,我可以非常愉快地处理LoggedIn事件,以正确地将用户重定向到正确的位置。我想做的是: 1)完全从查询字符串中删除ReturnURL 2)在呈现LoginStatus控件时能够控制ReturnURL。

我已经完成了System.Web.UI.WebControls.LoginStatus的一些Reflector,看起来它是硬编码的,总是使用ReturnURL,基于以下代码:

private string NavigateUrl
{
    get
    {
        if (!base.DesignMode)
        {
            return FormsAuthentication.GetLoginPage(null, true);
        }
        return "url";
    }
}

始终将reuseReturnURL设置为true。

可能,我唯一的选择是滚动我自己的LoginStatus控件吗?

[编辑:最初为了简洁起见,我省略了以下细节]

这是我想要实现的一个非常简单的例子:

Web应用程序项目具有以下结构: 网站   - 控制    - 组件       - Footer.ascx       - Header.ascx   - MasterPages     - Site.Master   - Default.aspx   - Login.aspx

如果您有兴趣,页面标记如下。

我已经创建了Web用户控件来分离关注点,但是在Login页面上使用asp:Login控件需要嵌套在(服务器端)表单中。 asp:LoginStatus控件也需要嵌套在(服务器端)表单中。由于页面上不能有多个服务器端表单,因此会中断。

此外,答案不仅仅是在Login页面上禁止LoginStatus控件。想象一下,如果我只是想在主页面上添加一个小的搜索控件,它也依赖于(服务器端)表单。因此,使用Server.Execute并从ASPX生成页面的原因。这个<!>“技巧<!>”; .NET允许在页面上使用多个服务器端表单。 (不要问我怎么......我不知道!)

也许我的整个架构设计都是错误的,但是其他人如何在需要服务器端表单的页面上拥有多个Web用户控件?或者不是吗?

Site.Master标记:

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebSite.MasterPages.Site" %>

<%@ Register TagPrefix="bs" TagName="Footer" Src="~/Controls/Components/Footer.ascx" %>
<%@ Register TagPrefix="bs" TagName="Header" Src="~/Controls/Components/Header.ascx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body id="Body" runat="server">
    <div id="container">
        <!-- start header -->
        <bs:Header ID="Header" runat="server" />
        <!-- end header -->
        <div id="central">
            <div id="main">
                <asp:PlaceHolder ID="MainContentPlaceHolder" runat="server">
                    <!-- start main content -->
                    <div>
                        <asp:ContentPlaceHolder ID="MainContent" runat="server" />
                    </div>
                    <!-- end main content -->
                </asp:PlaceHolder>
            </div>
        </div>
        <!-- start footer -->
        <bs:Footer ID="Footer" runat="server" />
        <!-- end footer -->
    </div>

</body>
</html>

Default.aspx标记:

<%@ Page MasterPageFile="~/MasterPages/Site.Master" Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebSite._Default" %>

<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="MainContent">
    Main Body Content <br />
    <br />

</asp:Content>

Header.ascx标记:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Header.ascx.cs" Inherits="WebSite.Controls.Components.Header" %>
<div id="header">
    Header Content <br />
    <div id="loginstatus">
        <form id="Form1" runat="server">
        <asp:LoginView ID="displayloginname" runat="server">
            <AnonymousTemplate>
                <a href="../../Registration.aspx">Register</a>
            </AnonymousTemplate>
            <LoggedInTemplate>
                Welcome
                <asp:LoginName runat="server" ID="ctlLoginName" />
            </LoggedInTemplate>
        </asp:LoginView>
        <asp:LoginStatus ID="displayloginstatus" runat="server" LoginText="Login" LogoutPageUrl="~/Default.aspx"
            LogoutAction="Redirect" />
        </form>

        <br />
    </div>
</div>

Footer.ascx标记:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Footer.ascx.cs" Inherits="Website.Controls.Components.Footer" %>

        <div id="footer">
            Footer Content
            <ul class="links">
            <asp:PlaceHolder ID="ListItems" Runat="server">
                <li><a runat="server" id="HomeLink" href="~/">Home</a></li>
                <li><a runat="server" href="~/" ID="A1">About Us</a></li>
                <li><a id="A2" runat="server" href="~/">Contact Us</a></li>
                <li><a id="A3" runat="server" href="~/">Privacy Policy</a></li>
                <li><a id="A4" runat="server" href="~/">Accessibility Policy</a></li>
                <li><a id="A5" runat="server" href="~/">Legal Notices</a></li>
                <li><a id="A6" runat="server" href="~/">Sitemap</a></li>
                <li><a id="A7" runat="server" href="~/">RSS Feeds</a></li>
            </asp:PlaceHolder>
            </ul>

        </div>

Login.aspx标记:

<%@ Page MasterPageFile="~/MasterPages/Site.Master" Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="Website.Login" %>

<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="MainContent">
    Main Body Content <br />
    <br />
    <form id="form1" runat="server">
    <div>

        <asp:Login ID="Login1" runat="server">
        </asp:Login>

    </div>
    </form>
</asp:Content>
有帮助吗?

解决方案

我看到两个选项:

  1. 将表单标记放在母版页中。就在<div id="container" <!> gt下面;并将所有内容包装在该div中。
  2. 将标题更改为不需要ASP.NET表单。不确定LoginView或LoginStatus是否都需要ASP.NET表单。然后,您可以保留使用母版页的aspx文件的表单标记(就像您在Login.aspx中一样)。我更喜欢将表单标签放在aspx页面中(而不是在主文件中),并确保页眉和页脚不需要ASP.NET表单(他们可以使用常规表单标签,而不是使用runat = server)。

其他提示

为什么要从Header.ascx执行Header.aspx的Server.Execute?为什么不把Header.aspx代码放在Header.ascx中。这样ReturnUrl将成为您期望的页面。

这里听起来不太正确:

  Page_Lo上的

执行Server.Execute(<!> quot;〜/ Controls / Pages / Header.aspx <!>;)
  并将内容写入Literal

我不明白你为什么要这样做?您提到这是因为您试图解决ASP.NET不允许在页面上使用多个HtmlForm的问题。但是,如果您只是将header.aspx中的html内容放入文字中,那么您是不是在使用HtmlForm?那么你可以将Header.aspx的内容放在普通的表单标签中(没有runat = server)吗?或者登录状态控件是否可以完全放在表单之外? Header.aspx的内容真的需要一个表格吗?

我会好好看看你为什么要将header.aspx页面的内容写入文字并尝试解决问题,而不是潜入LoginStatus控件并更改它以执行它不打算做的事情要做。

另一个可能的建议:如果你确实需要将Header加载到文字中,你可以使用Page.LoadUserControl吗?这可能会自动为您解析网址?不过100%肯定。

scroll top