2009-06-17 45 views
0

我有一个使用ASP.NET Login Controls和Forms Authentication的网站。我已将asp:LoginStatus控件放置在另一个Web用户控件中,该控件管理我网站的页眉部分的显示。ASP.NET LoginStatus控件 - 在生成的QueryString中覆盖ReturnURL

我遇到的问题是由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的一些反射-ING和看来,它是硬编码为始终使用RETURNURL,基于以下代码:

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

它始终将reuseReturnURL设置为true。

可能,我唯一的选择是推出我自己的LoginStatus控件?

[编辑:最初为简便起见,我省略了以下详细信息]

这里是什么,我想acheive一个非常简单的例子:

Web应用程序项目的结构如下: 网页 - 控制 - 组件 - Footer.ascx - Header.ascx - MasterPages - 的Site.Master - Default.aspx的 - 为Login.aspx

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

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

此外,答案不仅仅是抑制登录页面上的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> 

回答

0

我看到两个选项:

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

你为什么这样做的Header.aspx从您Header.ascx一个使用Server.Execute?为什么不把Header.aspx代码放在Header.ascx中?这样ReturnUrl将成为您期望的页面。

0

东西听起来不完全正确的位置:

上的Page_Load执行使用Server.Execute( “〜/控制/页/ Header.aspx”)
和写入文字

内容出

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

我会仔细看看为什么要将header.aspx页面的内容写入文字并尝试修复问题,而不是潜入LoginStatus控件并将其更改为执行某些操作打算去做。

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

+0

我会编辑我的问题以提供更多信息... – plancake 2009-06-17 04:11:48

+0

回答您的问题... 1)asp:LoginStatus控件需要一个服务器端表单,所以是的,我的标题(控件或页面,哪个不重要)需要服务器端表单。 2)asp:登录控件也需要一个服务器端表单。也许这是我的问题所在,我如何在同一页面上有两个Web用户控件,都需要服务器端表单? – plancake 2009-06-17 04:36:32