ASP.NET Login Steuerung - Überschreiben der ReturnURL in generierten Abfrage-Zeichenfolge

StackOverflow https://stackoverflow.com/questions/1004630

  •  05-07-2019
  •  | 
  •  

Frage

Ich habe eine Website, die die ASP.NET-Anmeldungssteuer und Formularauthentifizierung. Ich habe die asp gelegt: Login Steuerelement in einem anderen Web User Control, die die Anzeige des Header-Teil meiner Website verwaltet.

Das Problem, das ich habe ist, dass die ReturnURL durch die Steuerlogin präsentierte Referenzen den Pfad zu der Header-Kontrolle, nicht die Seite der Benutzer gerade befindet. Dies ist wahrscheinlich auf Grund der Klassenhierarchie und die Header-Control (ascx) tatsächlich verwendet Server.Execute auf einer ASPX-Datei, um die HTML zu erzeugen. Dies ist eine Arbeit um das Problem der nicht in der erlaubt zu vermeiden, auf einer Seite mehr als ein serverseitige Form.

So ist die eigentliche Klasse Hierarchie der Seite wie folgt:

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>

Wenn der Benutzer klickt auf dem Login-Link sie zu Login.aspx korrekt weitergeleitet werden, aber die ReturnURL angezeigt ist (falsch - obwohl ich verstehen kann, warum). "ReturnUrl=%2fControls%2fPages%2fHeader.aspx"

Wenn Sie auf der Login-Seite kann ich ganz glücklich das LoggedIn Ereignis behandeln, um die korrekte Benutzer an die richtige Stelle weitergeleitet werden. Was ich möchte, ist zu tun, entweder: 1) Entfernen Sie die ReturnURL aus dem Query-String zusammen 2) Die Lage sein, die ReturnURL zu steuern, wenn die Login Steuerung gemacht wird.

Ich habe einige Reflector-ing des System.Web.UI.WebControls.LoginStatus getan und es scheint, dass es hart codiert ist immer eine ReturnURL zu verwenden, basierend auf den folgenden Code:

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

Es ist immer reuseReturnURL auf true setzen.

Möglicherweise ist meine einzige Wahl ist meine eigene Login Kontrolle zu rollen?

[EDIT: Ursprünglich für die der Kürze halber weggelassen ich die folgenden Details]

Hier ist ein wirklich einfaches Beispiel dafür, was ich acheive versuchen:

Web Application Project hat die folgende Struktur: Webseite  - Kontrollen    - Komponenten      - Footer.ascx      - Header.ascx  - Masterpages    - Site.Master  - Default.aspx  - Login.aspx

Die Seite Markups sind unten, wenn Sie interessiert sind.

Ich habe die Web User Control für die Trennung von Bedenken erstellt, jedoch auf der Login-Seite die asp zu verwenden: Login Kontrollen sie in einer (serverseitig) Form verschachtelt werden müssen. Die asp: Loginstatus Steuerung muss auch in einem (serverseitigen) -Form verschachtelt werden. Da Sie nicht mehr als eine serverseitige Formular auf einer Seite haben kann, diese bricht.

Auch ist die Antwort nicht nur den Loginstatus-Steuerelement auf der Login-Seite zu unterdrücken. Stellen Sie sich vor, wenn ich eine wenig Suchsteuerung auf der Hauptseite nur hinzufügen wollte, die auch auf einer (serverseitig) Form verlassen würde. Dies ist der Grund für eine Server.Execute verwenden und eine Seite aus einem ASPX zu erzeugen. Dieser „Tricks“ .NET in mehr serverseitige Formulare auf einer Seite erlaubt. (Fragen Sie mich nicht, wie ... ich weiß es nicht!)

Vielleicht Design meine gesamte Architektur ist falsch, aber, wie andere haben mehrere Web User Controls auf einer Seite, die serverseitige Formulare benötigen? Oder nicht wahr?

Site.Master Markup:

<%@ 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 Markup:

<%@ 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 Markup:

<%@ 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 Markup:

<%@ 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 Markup:

<%@ 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>
War es hilfreich?

Lösung

Ich sehe zwei Möglichkeiten:

  1. Legen Sie Ihre Formular-Tag in der Masterseite. Direkt unter den <div id="container"> und Verpackung alle Inhalte in diesem div.
  2. Ändern Sie Ihre Header nicht eine ASP.NET Form. Nicht sicher, ob die Loginview oder Login beide erfordern eine ASP.NET-Form. Und dann können Sie das Formular-Tag für die aspx Dateien führen, die die Masterseite verwenden (wie Sie in Login.aspx haben). Dies ist, was ich lieber nur auf Formular-Tags in aspx Seiten (nicht in Master-Dateien) setzen und sicher Kopf- und Fußzeile macht keine ASP.NET Form muß (sie einen regelmäßigen Form-Tag einfach nicht mit runat = Server verwenden könnten).

Andere Tipps

Warum tun Sie eine Server.Execute der Header.aspx von Ihrem Header.ascx? Warum Sie nicht einfach den Header.aspx Code setzen in der Header.ascx. Auf diese Weise die ReturnUrl die Seite sein wird, erwarten Sie es sein.

Etwas klingt nicht ganz richtig hier:

  

auf Page_Load führt eine Server.Execute ( "~ / Steuerungen / Pages / Header.aspx")
  und schreibt den Inhalt, um die wörtlichen

Ich verstehe nicht, warum Sie dies tun? Sie erwähnen, dass es ist, weil Sie, um das Problem von ASP.NET nicht mehr als ein Htmlform ermöglicht auf einer Seite zu bekommen versuchen. Aber wenn Sie nur die HTML-Inhalte von header.aspx in einer wörtlichen Umsetzung dann verwenden Sie keine Htmlform ?? So können Sie den Inhalt von Header.aspx setzen gerade in einem normalen Form-Tag (ohne runat = Server)? Oder kann die Login-Status Kontrolle außerhalb des Formulars ganz wird gestellt? Sie müssen die Inhalte von Header.aspx wirklich eine Form in erster Linie?

Ich würde einen guten Blick auf, warum Sie den Inhalt Ihrer header.aspx-Seite zu einem wörtlichen schreiben und versuchen, das Problem dort statt Tauchen in die Login Kontrolle zu beheben und zu ändern es etwas zu tun, es nicht beabsichtigt ist, zu tun.

Ein anderer möglicher Vorschlag: Wenn Sie wirklich tun müssen, um Header in eine wörtlichen zu laden, können Sie Page.LoadUserControl statt? Dies kann automatisch die URLs für Sie lösen? Nicht 100% sicher, though.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top