![]() |
Benötige Hilfe bei TPageProducer
Hallo Leute,
schreibe gerade an einer ISAPI Extension für den IIS (Srv. 08/12). Soweit so gut, alles funktioniert wie es soll, nun will der Kunde natürlich seine eigene Templates verwenden. Ok, Templates mit Tags bestückt (<#MeinTag>) und den TPageProducer (PP) für die Verarbeitung vorbereitet. Das haut auch bestens hin, bis mir beim debuggen auffiel, dass der PP im OnHTMLTag die Tags zweimal ersetzt und das ist sehr, sehr schlecht. Ich verwende mit unter ein "Data Modul" das verschiedene Werte verarbeitet und im OnHTMLTag des PP die Werte den Tags zuweist. Hier mal etwas BeispielCode:
Delphi-Quellcode:
Also wenn OnHTMLTag aufgerufen wird dann passiert folgendes:
procedure TWebModuleMain.PageProducer1HTMLTag(Sender: TObject; Tag: TTag;
const TagString: string; TagParams: TStrings; var ReplaceText: string); var dm: TDataModuleHtml; begin dm := TDataModuleHtml.Create(nil); try if SameText(TagString, 'TAG_1') then ReplaceText := dm.GetBlaBla1 else if SameText(TagString, 'TAG_2') then ReplaceText := dm.GetBlaBla2 // Usw... else ReplaceText := ''; finally dm.Free; end; end; end. procedure TWebModuleMain.WebModuleMainDefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin PP.HTMLFile := Request.TranslateURI('/templates/template1.html'); Response.Content := PP.Content; end; 1. DataModule (dm) wird erstellt 2. Er findet den ersten Tag und ersetzt diesen mit dem Wert der function dm.GetBlaBla1 3. Springt ins finally 4. Erstellt DM 5. Findet den zweiten Tag und ersetzt diesen mit dem Wert der func. dm.GetBlaBla2 6. Springt ins finally Nun sind alle Tags ersetzt und das wars dachte ich, doch dann fängt alles von vorne an. Nachdem der zweite Durchlauf beendet ist, spuckt er die Seite aus. Wenn ich nun in den Tamplates nur eine einzige Tag-Stelle setze, dann macht der PP das richtig. Damit meine ich, der Tag wird ersetzt und der PP geht aus der Methode raus und Ende. Das Problem hierbei ist, das die function dm.GetBlaBla1 aus dem DataModule z.B. Werte von einem anderen Server abfragt und die function dm.GetBlaBla1 womöglich auch. Im Umkehrschluss bedeutet das, um so mehr Tags ich im Template habe um so mehr Fremd-Serveraufrufe ich damit produziere. Wie kann ich das abstellen? Mache ich bei der Verwendung des TPageProducer generell einen Fehler? Ist diese Komponente dafür gedacht oder nur für
Delphi-Quellcode:
?
PP.ReplaceText := 'Hallo ' +Request.ContentFields.Values['FirstName'] + ', Guten Tag'
Danke Alexander |
AW: Benötige Hilfe bei TPageProducer
Du beschreibst das so, als ob OnHTMLTag wie in einer Schleife durchlaufen wird. Das ist aber nicht ganzh so. Er Content des PP wird durchlaufen und jedesmal wenn er auf einen Tag trifft wird die Funktion OnHTMLTag aufgerufen. Daher wird dann auch jedesmal das Datenmodul neu erzeugt und freigegeben.
Evtl. wäre es hier sinnvoll, das DM als globales Objekt oder Feld anzulegen und per Lazyload bei bedarf einmalig zu erstellen wobei die benötigten Infos vom anderen Server geladen werden können und am Ende der Requestbearbeitung wieder freizugeben? |
AW: Benötige Hilfe bei TPageProducer
@Jumpy
Ja verstehe, es geht nicht um das DatenModul sondern um den doppelten Aufruf. Das DatenModul kann er zig mal erstellen, das macht nichts. Das Problem besteht darin, das der PP alle Tags doppelt durchläuft. Wenn der PP auf den ersten Tag trifft, ruft er eine Methode im DatenModul auf und füllt mit den erhaltenen Daten den Tag, z.B. TAG1. das geht ja in Ordnung. Das macht der auch mit dem zweiten Tag TAG2 und das ist auch im Sinn des Erfinders. So nun hat er alle Tags im HTML-Template durchlaufen und jedem Tag seinen Wert zugewiesen. Ob der das in einer Schleife macht oder wie auch immer, das ist nebensächlich. Von mir aus kann er nochmals das Dokument parsen, ob ein Tag vergessen wurde, auch Ok, aber der PageProducer ruft jeden Tag nochmals auf und verpasst ihm den Wert erneut egal ob schon geschehen oder nicht. So als mache er erst mal einen Probelauf um dann im zweiten Anlauf die Werte nochmals einzutragen. Leider finde ich nirgends eine gute Doku darüber. Deshalb meine Frage: Mache ich selbst was falsch? Falls ja, wie benutzt man die Komponente richtig. Oder, oder.... Danke, Alexander |
AW: Benötige Hilfe bei TPageProducer
Er durchläuft den Content meines Wissens nur 1x und durchsucht den auf Tags und zwar immer wenn du auf den Content zugreifst, sprich irgendwas:=pp.Content.
Ich muss aber gestehen, dass ich das nicht als ISAPI-Extension nutze sondern immer eigene CGI.exe erzeuge. Dabei arbeite ich dann mit WebActions, auf die die Requests "verteilt" werden. Jeder WebAction ist dann i.d.R. ein PageProducer zugeordnet der den Content liefert. Diese DefaultHandlerAction nutze ich dabei nicht, daher weiß ich nicht woran es bei dir liegen könnte. |
AW: Benötige Hilfe bei TPageProducer
Für die Nachwelt...
Die
Delphi-Quellcode:
besitzen die Eigenschaft
Web.HTTPApp.TWebModule
Delphi-Quellcode:
_
Web.HTTPApp.TCustomWebDispatcher.Actions
die wiederum die Eigenschaft
Delphi-Quellcode:
und
Web.HTTPApp.TWebActionItem.Producer
Delphi-Quellcode:
.
Web.HTTPApp.TWebActionItem.ProducerContent
Weist man dann einem der zwei im Objektinspektor den TPageProducer zu und ruft die
Delphi-Quellcode:
wie hier unten auf:
Web.HTTPApp.TCustomWebDispatcher.Actions
Delphi-Quellcode:
kommt es zu dem von mir geschilderten Verhalten. Das oben gezeigte funktioniert nur richtig, also ohne doppelten Aufruf,
procedure TWebModuleMain.WebModuleMainDefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin PP.HTMLFile := Request.TranslateURI('/templates/template1.html'); Response.Content := PP.Content; end; wenn im "Producer" und "ProducerContet" der Action nichts zugewiesen wurde! Falls doch, muss der Handler der Action wie folgt aussehen:
Delphi-Quellcode:
Vergessen darf man dann nicht, falls Templates dynamisch geladen werden sollen, die Templates z.B. im
procedure TWebModuleMain.WebModuleMainDefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.SendResponse; end;
Delphi-Quellcode:
zu laden
Web.HTTPApp.TWebModule.BeforeDispatch
Delphi-Quellcode:
.
PP.HTMLFile := 'C:\Template.html';
Die "BeforeDispatch" Ereignisbehandlungsroutine führt eine Vorverarbeitung durch bevor es zu der/den Action/s geht. Mehr siehe Hilfe unter: Zitat:
Alexander PS: So ein Sche** ich fass es nicht |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz