Ich versuche, eine sehr, sehr einfache "Micro-Webapp" zu erstellen, von der ich vermute, dass sie für einige Stack Overflow'rs von Interesse ist, wenn ich sie jemals fertig bekomme. Ich hoste es auf meiner C # in Depth-Site, die Vanilla ASP.NET 3.5 (dh nicht MVC) ist.
Der Ablauf ist sehr einfach:
- Wenn ein Benutzer die App mit einer URL betritt, die nicht alle Parameter angibt (oder wenn einer von ihnen ungültig ist), möchte ich nur die Benutzereingabesteuerelemente anzeigen. (Es gibt nur zwei.)
- Wenn ein Benutzer die App mit einer URL eingibt , das tut alle erforderlichen Parameter haben, möchte ich die Ergebnisse anzuzeigen und die Eingangskontrollen (so dass sie die Parameter ändern können)
Hier sind meine selbst auferlegten Anforderungen (Mischung aus Design und Implementierung):
- Ich möchte, dass die Einreichung GET anstelle von POST verwendet, hauptsächlich, damit Benutzer die Seite einfach mit einem Lesezeichen versehen können.
- Ich möchte nicht, dass die URL nach der Übermittlung albern aussieht, mit überflüssigen Kleinigkeiten. Nur die Haupt-URL und die realen Parameter bitte.
- Idealerweise möchte ich vermeiden, dass JavaScript benötigt wird. In dieser App gibt es keinen guten Grund dafür.
- Ich möchte während der Renderzeit auf die Steuerelemente zugreifen und Werte usw. festlegen können. Insbesondere möchte ich die Standardwerte der Steuerelemente auf die übergebenen Parameterwerte festlegen können, wenn ASP.NET dies nicht automatisch tun kann für mich (innerhalb der anderen Einschränkungen).
- Ich bin froh, die gesamte Parameterüberprüfung selbst durchführen zu können, und ich brauche nicht viel für serverseitige Ereignisse. Es ist wirklich einfach, alles auf Seitenladen einzustellen, anstatt Ereignisse an Schaltflächen usw. anzuhängen.
Das meiste davon ist in Ordnung, aber ich habe keine Möglichkeit gefunden , den Ansichtsstatus vollständig zu entfernen und den Rest der nützlichen Funktionalität beizubehalten. Mit dem Beitrag aus diesem Blog-Beitrag habe ich es geschafft, zu vermeiden, dass ein tatsächlicher Wert für den Ansichtsstatus erhalten wird - aber er endet immer noch als Parameter in der URL, was wirklich hässlich aussieht.
Wenn ich es zu einem einfachen HTML-Formular anstelle eines ASP.NET-Formulars runat="server"
mache (dh herausnehmen), erhalte ich keinen magischen Ansichtsstatus - aber dann kann ich nicht programmgesteuert auf die Steuerelemente zugreifen.
All dies könnte ich tun, indem ich den größten Teil von ASP.NET ignoriere, ein XML-Dokument mit LINQ to XML aufbaue und implementiere IHttpHandler
. Das fühlt sich allerdings etwas niedrig an.
Mir ist klar, dass meine Probleme gelöst werden können, indem ich entweder meine Einschränkungen lockere (z. B. POST verwende und mich nicht um den Überschussparameter kümmere) oder ASP.NET MVC verwende. Sind meine Anforderungen jedoch wirklich unangemessen?
Vielleicht ASP.NET skaliert einfach nicht nach unten auf diese Art von app? Es gibt jedoch eine sehr wahrscheinliche Alternative: Ich bin nur dumm und es gibt eine ganz einfache Möglichkeit, die ich einfach nicht gefunden habe.
Irgendwelche Gedanken, irgendjemand? (Cue-Kommentare darüber, wie die Mächtigen gefallen sind usw. Das ist in Ordnung - ich hoffe, ich habe nie behauptet, ein ASP.NET-Experte zu sein, da die Wahrheit genau das Gegenteil ist ...)
Antworten:
Mit dieser Lösung erhalten Sie programmgesteuerten Zugriff auf die Steuerelemente in ihrer Gesamtheit, einschließlich aller Attribute auf den Steuerelementen. Außerdem werden bei der Übermittlung nur die Textfeldwerte in der URL angezeigt, sodass Ihre GET-Anforderungs-URL "aussagekräftiger" ist.
Dann können Sie in Ihrem Code-Behind alles tun, was Sie für PageLoad benötigen
Wenn Sie kein Formular mit haben möchten
runat="server"
, sollten Sie HTML-Steuerelemente verwenden. Es ist einfacher, für Ihre Zwecke zu arbeiten. Verwenden Sie einfach normale HTML-Tagsrunat="server"
und geben Sie ihnen eine ID. Dann können Sie programmgesteuert darauf zugreifen und ohne a codierenViewState
.Der einzige Nachteil ist, dass Sie keinen Zugriff auf viele der "hilfreichen" ASP.NET-Serversteuerelemente wie
GridView
s haben. Ich habe aRepeater
in mein Beispiel aufgenommen, weil ich davonRepeater
ausgehe, dass Sie die Felder auf derselben Seite wie die Ergebnisse haben möchten und (meines Wissens) a das einzige DataBound-Steuerelement ist, das ohnerunat="server"
Attribut im Formular-Tag ausgeführt wird.quelle
Sie sind definitiv (IMHO) auf dem richtigen Weg, indem Sie nicht runat = "server" in Ihrem FORM-Tag verwenden. Dies bedeutet jedoch nur, dass Sie Werte direkt aus dem Request.QueryString extrahieren müssen, wie in diesem Beispiel:
Auf der ASPX-Seite selbst:
und im Code-Behind:
Der Trick dabei ist, dass wir ASP.NET-Literale in den Attributen value = "" der Texteingaben verwenden, sodass die Textfelder selbst nicht runat = "server" müssen. Die Ergebnisse werden dann in ein ASP: Panel verpackt und die Visible-Eigenschaft beim Laden der Seite festgelegt, je nachdem, ob Sie Ergebnisse anzeigen möchten oder nicht.
quelle
Okay, Jon, zuerst das Viewstate-Problem:
Ich habe seit 2.0 nicht mehr überprüft, ob sich der interne Code geändert hat, aber hier ist, wie ich vor einigen Jahren damit umgegangen bin, den Viewstate loszuwerden. Tatsächlich ist dieses versteckte Feld in HtmlForm fest codiert, daher sollten Sie Ihr neues ableiten und in dessen Rendering einsteigen und die Aufrufe selbst ausführen. Beachten Sie, dass Sie __eventtarget und __eventtarget auch weglassen können, wenn Sie sich an einfache alte Eingabesteuerelemente halten (was Sie wahrscheinlich möchten, da dies auch dazu beiträgt, dass JS auf dem Client nicht erforderlich ist):
Also holst du dir diese 3 statischen MethodInfos und rufst sie aus, indem du diesen Viewstate-Teil überspringst;)
und hier ist der Typkonstruktor Ihres Formulars:
Wenn ich Ihre Frage richtig stelle, möchten Sie POST auch nicht als Aktion für Ihre Formulare verwenden. So gehen Sie vor:
Ich denke das ist so ziemlich alles. Lass mich wissen, wie es geht.
BEARBEITEN: Ich habe die Methoden für den Seitenaufrufstatus vergessen:
So erhält Ihr benutzerdefiniertes Formular: HtmlForm seine brandneue Zusammenfassung (oder nicht) Seite: System.Web.UI.Page: P.
In diesem Fall versiegele ich die Methoden, weil Sie die Seite nicht versiegeln können (auch wenn sie nicht abstrakt ist. Scott Guthrie wird sie in eine weitere einbinden: P), aber Sie können Ihr Formular versiegeln.
quelle
Haben Sie darüber nachgedacht, den POST nicht zu entfernen, sondern zu einer geeigneten GET-URL umzuleiten, wenn das Formular POST ist? Akzeptieren Sie also sowohl GET als auch POST, aber erstellen Sie beim POST eine GET-Anforderung und leiten Sie zu dieser um. Dies kann entweder auf der Seite oder über ein HttpModule erfolgen, wenn Sie es seitenunabhängig machen möchten. Ich denke, das würde die Dinge viel einfacher machen.
EDIT: Ich gehe davon aus, dass Sie EnableViewState = "false" auf der Seite gesetzt haben.
quelle
Ich würde ein HTTP-Modul erstellen, das das Routing handhabt (ähnlich wie MVC, aber nicht ausgefeilt, nur ein paar
if
Anweisungen) und es anaspx
oderashx
Seiten übergeben.aspx
wird bevorzugt, da es einfacher ist, die Seitenvorlage zu ändern. Ich würdeWebControls
dasaspx
aber nicht benutzen . EinfachResponse.Write
.Übrigens können Sie zur Vereinfachung die Parameterüberprüfung im Modul durchführen (da es wahrscheinlich Code mit dem Routing teilt) und ihn speichern
HttpContext.Items
und dann auf der Seite rendern. Dies funktioniert ziemlich ähnlich wie beim MVC ohne all die Glocken und Pfeifen. Dies ist, was ich vor ASP.NET MVC-Tagen viel getan habe.quelle
Ich war wirklich froh, die Seitenklasse komplett verlassen zu haben und einfach jede Anfrage mit einem großen Schalter zu bearbeiten, der auf der URL basiert. Jede "Seite" wird zu einer HTML-Vorlage und einem ac # -Objekt. Die Vorlagenklasse verwendet einen regulären Ausdruck mit einem Übereinstimmungsdelegierten, der mit einer Schlüsselsammlung verglichen wird.
Leistungen:
bummers:
Jon, was machen wir an einem Samstagmorgen auf SO :)?
quelle
Ich dachte, die asp: Repeater-Steuerung sei veraltet.
Die ASP.NET-Vorlagen-Engine ist nett, aber Sie können das Wiederholen genauso einfach mit einer for-Schleife durchführen ...
ASP.NET Forms ist in Ordnung, es gibt gute Unterstützung von Visual Studio, aber diese Sache mit runat = "server" ist einfach falsch. ViewState to.
Ich schlage vor, Sie werfen einen Blick darauf, was ASP.NET MVC so großartig macht, wen es vom ASP.NET Forms-Ansatz entfernt, ohne alles wegzuwerfen.
Sie können sogar Ihre eigenen Build-Provider-Inhalte schreiben, um benutzerdefinierte Ansichten wie NHaml zu kompilieren. Ich denke, Sie sollten hier nach mehr Kontrolle suchen und sich einfach auf die ASP.NET-Laufzeit verlassen, um HTTP und als CLR-Hosting-Umgebung zu verpacken. Wenn Sie den integrierten Modus ausführen, können Sie auch die HTTP-Anforderung / Antwort bearbeiten.
quelle