2009-10-10 4 views
2

J'ai créé un simple HttpModule et un flux de réponse pour reformater la sortie rendue des pages Web (voir les extraits de code ci-dessous).Filtre de réponse ASP.NET pour reformater la sortie rendue des pages ASPX?

Dans le HttpModule je mis le Response.Filter à mon PageStream:

m_Application.Context.Response.Filter = new PageStream(m_Application.Context); 

Dans le PageStream j'écrasent la méthode Write pour faire mon reformatage de la sortie rendu:

public override void Write(byte[] buffer, int offset, int count) 
{ 
    string html = System.Text.Encoding.UTF8.GetString(buffer); 
    //Do some string resplace operations here... 
    byte[] input = System.Text.Encoding.UTF8.GetBytes(html); 
    m_DefaultStream.Write(input, 0, input.Length); 
} 

Et ce travail fonctionne correctement lorsque vous l'utilisez sur des pages HTML simples (.html), mais lorsque j'utilise cette méthode sur des pages ASPX (.aspx), la méthode Write est appelée plusieurs fois, divisant le reformatage en plusieurs étapes et potentiellement détruit le opérations de remplacement de chaîne.

Comment résoudre ce problème? Existe-t-il un moyen de laisser la page ASPX PAS appeler Write plusieurs fois, par ex. en changeant sa taille de tampon, ou ai-je choisi la mauvaise approche entièrement, en utilisant cette méthode Response.Filter pour manipuler la sortie rendue?

Répondre

2

guidé par l'article proposé par Darin Dimitrov, je me suis retrouvé avec la mise en œuvre suivante de la méthode Write qui fonctionne aussi parfaitement avec les pages ASPX:

public override void Write(byte[] buffer, int offset, int count) 
{ 
    string strBuffer = System.Text.UTF8Encoding.UTF8.GetString (buffer, offset, count); 

    if (!strBuffer.Contains("</html>")) 
    { 
     m_ResponseHtml.Append(strBuffer); 
    } 
    else 
    { 
     m_ResponseHtml.Append(strBuffer); 
     string html = m_ResponseHtml.ToString(); 

     //Do some string operations here... 
     byte[] input = System.Text.Encoding.UTF8.GetBytes(html); 
     m_DefaultStream.Write(input, 0, input.Length);   
    } 
} 

Th Le code utilise un StringBuilder (m_ResponseHtml) pour accumuler tout le code HTML, avant d'effectuer la manipulation de chaîne sur la sortie rendue.

1

Vous pourriez avoir besoin de vérifier le type de contenu avant de fixer le filtre de réponse:

var response = m_Application.Context.Response; 
if (response.ContentType == "text/html") 
{ 
    response.Filter = new PageStream(m_Application.Context); 
} 

Il y a aussi une belle article décrivant les filtres de réponse dans ASP.NET.

+0

Bien que votre réponse n'a pas de sens par rapport à ma question, je vérifie naturellement le type de contenu avant de définir le Response.Filter, l'article fourni m'a aidé. Merci. – PropellerHead

2

Je voudrais juste tamponner les données dans la méthode Write et effectuer les opérations de chaîne dans la méthode Close, comme ceci:

private readonly Stream _forwardStream; 
private readonly StringBuilder _sb; 

// snip 

public override void Write (byte[] buffer, int offset, int count) 
{ 
    string chunk = Encoding.UTF8.GetString (buffer, offset, count); 
    _sb.Append (chunk); 
} 

public override void Close() 
{ 
    string result = GetManipulatedString(); 

    byte[] rawResult = Encoding.UTF8.GetBytes (result); 
    _forwardStream.Write (rawResult, 0, rawResult.Length); 

    base.Close(); 
    _forwardStream.Close(); 
} 

(peut-être encore mieux si vous collectez les données dans un MemoryStream)

0

La réponse de PropellerHead repose sur la recherche de la balise html de fermeture dans le tampon final, mais j'avais effectivement le tampon final trop petit pour contenir l'étiquette entière.

Une méthode plus sûre (et plus efficace) consiste à ne faire que l'ajout dans Write et à faire ensuite les opérations de chaîne et à les afficher dans Close.

Questions connexes