2009-08-12 3 views
0

Ich habe eine aspx-Seite, die reguläre HTML, einige uicomponents und mehrere Tokens der Form {tokename} enthält.Ersetze Tokens in einer aspx-Seite beim Laden

Wenn die Seite geladen wird, möchte ich den Seiteninhalt analysieren und diese Token durch den richtigen Inhalt ersetzen. Die Idee ist, dass es mehrere Vorlagenseiten geben wird, die den gleichen Codebehind verwenden.

Ich habe keine Probleme Parsen der String-Daten selbst (siehe named string formatting, replace tokens in template) mein Problem liegt in, wenn zu lesen, und wie die Daten zurück auf die Seite zu schreiben ...

Was ist der beste Weg, für mich, den Seiteninhalt neu zu schreiben? Ich habe einen Streamreader verwendet und die Seite durch Response.Write ersetzt, aber das ist nicht gut - eine Seite, die andere .net-Komponenten enthält, wird nicht korrekt dargestellt.

Alle Vorschläge würden sehr geschätzt werden!

Antwort

0

Vielen Dank an diejenigen, die auf diese Frage beigetragen, aber ich am Ende eine andere Lösung mit bis -

die Funktion als pro this page machen Aufschalten, außer ich den Seiteninhalt für mehrere verschiedene Tags mit regulären Ausdrücken analysiert.

protected override void Render(HtmlTextWriter writer) 
    { 
     if (!Page.IsPostBack) 
     { 
      using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) 
      { 
       using (System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(stream)) 
       { 
        HtmlTextWriter htmlWriter = new HtmlTextWriter(streamWriter); 
        base.Render(htmlWriter); 
        htmlWriter.Flush(); 
        stream.Position = 0; 
        using (System.IO.StreamReader oReader = new System.IO.StreamReader(stream)) 
        { 
         string pageContent = oReader.ReadToEnd(); 
         pageContent = ParseTagsFromPage(pageContent); 
         writer.Write(pageContent); 
         oReader.Close(); 
        } 
       } 
      } 
     } 
     else 
     { 
      base.Render(writer); 
     } 
    } 

Hier ist die regex-Tag-Parser

private string ParseTagsFromPage(string pageContent) 
    { 
     string regexPattern = "{zeus:(.*?)}"; //matches {zeus:anytagname} 
     string tagName = ""; 
     string fieldName = ""; 
     string replacement = ""; 
     MatchCollection tagMatches = Regex.Matches(pageContent, regexPattern); 
     foreach (Match match in tagMatches) 
     { 
      tagName = match.ToString(); 
      fieldName = tagName.Replace("{zeus:", "").Replace("}", ""); 
      //get data based on my found field name, using some other function call 
      replacement = GetFieldValue(fieldName); 
      pageContent = pageContent.Replace(tagName, replacement); 
     } 
     return pageContent; 
    } 

scheint ganz gut zu funktionieren, wie es in der GetFieldValue Funktion können Sie Ihre Feldnamen in irgendeiner Weise verwenden können, die Sie wünschen.

1

Werfen Sie einen Blick auf System.Web.UI.Adapters.PageAdapter Methode TransformText - in der Regel wird es für die Unterstützung mehrerer Geräte verwendet, aber Sie können Ihre Seite mit diesem nachbearbeiten.

1

Ich bin mir nicht sicher, ob ich Ihre Frage zu beantworten bin, aber ... Wenn Sie Ihre Schreibweise von

{tokenname} 

um so etwas wie

<%$ ZeusExpression:tokenname %> 

Sie Erstellen könnte erwägen ändern können Ihre System.Web.Compilation.ExpressionBuilder.

Nachdem Sie Ihren Kommentar zu lesen ...

Es gibt andere Möglichkeiten des Zugriffs auf die aktuelle Seite immer Expression mit: nur ... einen Ausdruck erstellen. nur ein bisschen die Probe von MSDN ;-) ändern und den Code Ihrer Seiten der Annahme enthalten ein Verfahren wie dieses

public object GetData(string token); 

Sie so etwas wie dieses

public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) 
{ 
    Type type1 = entry.DeclaringType; 
    PropertyDescriptor descriptor1 = TypeDescriptor.GetProperties(type1)[entry.PropertyInfo.Name]; 
    CodeExpression[] expressionArray1 = new CodeExpression[1]; 
    expressionArray1[0] = new CodePrimitiveExpression(entry.Expression.Trim()); 

    return new CodeCastExpression(
     descriptor1.PropertyType, 
     new CodeMethodInvokeExpression(
      new CodeThisReferenceExpression(), 
      "GetData", 
      expressionArray1)); 
} 

Dies ersetzt die Platzhalter durch ein implementieren könnte nennen wie diese

(string)this.GetData("tokenname"); 

natürlich kann man viel mehr näher darauf eingehen kann, vielleicht ein „Utility-Methode“ zu vereinfachen und zu „schützen“ Zugriff auf die Daten (a Zugriff auf Eigenschaften, keine spezielle Methode, Fehlerbehandlung, etc.).

Etwas, das statt mit (zum Beispiel)

(string)Utilities.GetData(this, "tokenname"); 

this helps ersetzt.

+0

Problem ist, ich brauche Daten von meiner aktuellen Seite, um den Ersatztext zu rendern - nicht sicher, ob ich Dinge von meiner aktuellen Seite an den Ausdrucksersteller übergeben kann? Ich fand gerade eine Lösung tatsächlich ... vielleicht sollte ich meine eigene Frage beantworten, falls andere sich wundern – RYFN

+0

Ja, ich stimme zu, dass Sie Ihre eigene Lösung präsentieren sollten. Jedenfalls habe ich meinen Vorschlag bearbeitet, um einige Ihrer Bedenken zu beantworten. –

Verwandte Themen