2009-10-15 8 views
2

J'ai deux pages sur mon site qui sont peuplées avec le contenu d'une base de données ainsi que des champs saisis par l'utilisateur (ne demandez pas!). Les pages contiennent également un ListView avec une DataList imbriquée. Il y a des boutons sur ces pages qui, lorsque vous cliquez dessus, récupèrent le contenu html de la page, l'écrivent dans un HtmlTextWriter puis récupèrent le texte et le placent dans un email.Email contenu de Asp.Net page

Ce que je dois faire est de remplacer toute TextBox/DropDownLists dans la source html avec des équivalents littéraux de chaîne avant de mettre dans l'email.

Mon code ASPX donc ressemble beaucoup quelque chose comme ceci:

<div id="mailableContent" runat="server"> 
    <asp:TextBox ID="txtMessage" runat="server"/> 
    <asp:Label ID="lblContentFromDb" runat="server"/> 
    <asp:ListView ID="lvwOffices" runat="server"> 
     //loads of stuff here including more textboxes for the user to fill in 
    </asp:ListView> 
</div> 

et codebehind est quelque chose comme ceci:

StringBuilder stringBuilder = new StringBuilder(); 
StringWriter writer = new StringWriter(stringBuilder); 
HtmlTextWriter htmlWriter = new HtmlTextWriter(writer); 
mailableContent.RenderControl(htmlWriter); 
MailMessage message = new MailMessage(); 
//do more stuff to set up the message object 
message.Body = stringBuilder.ToString(); 
//send the message 

Mes idées à ce jour sont à 1. définir manuellement les zones de texte Visible = false puis remplit les contrôles littéraux avec les valeurs correspondantes de la zone de texte, ce qui est plutôt désordonné et fastidieux. Remarque: Je dois supprimer les contrôles de saisie, sinon html pour que l'e-mail soit enveloppé avec un formulaire elemen que je ne veux pas vraiment faire. Y at-il un meilleur moyen de faire tout cela, je pense que peut-être faire quelques transformations xslt de style .Net1.1 avec le contenu de la page défini dans les fichiers xml pourrait être une meilleure façon d'aborder cela, mais je ne sais pas si cela traitera mon exigence où j'utilise actuellement un ListView avec une DataList imbriquée.

Répondre

1

Je trouve que ce que vous décrivez a beaucoup de frais généraux. Votre modèle d'e-mail reste-t-il pratiquement le même? Si oui, pourquoi ne pas simplement avoir un simple modèle html avec le code html 3. Il suffit ensuite de lire ce fichier à partir du disque et de remplacer les peices spécifiques (ie ## Name ##) avec le contenu dynamique. De cette façon, vous avez un contrôle complet sur le code HTML envoyé par e-mail et vous pouvez contrôler ce que les utilisateurs entrent.

cela limiterait également la charge de travail pour rendre le html compatible avec les clients de messagerie. Dans la suggestion précédente, je propose que l'implémentation de l'interface utilisateur et l'implémentation Email soient distinctes, ce qui permet à son tour de composer l'email avec plus de flexibilité. Sans l'aide

mailableContent.RenderControl(htmlWriter); 

cela vous permet également de composer le contenu du ListView à votre cahier des charges.

+0

Merci pour le sugge stion, mais comment cela répond-il à l'exigence ListView/DataList? –

+0

Je vais faire un deuxième essai, je ne suis pas sûr d'avoir compris la question. –

1

Couple d'idées:

  1. Utilisez RegEx pour remplacer la sortie html des zones de texte et DropDownLists avec plaintext. . (Tricky, avec la complication de trouver la substance <option selected="selected">

  2. Faites ce que je fais:

    • Créer une interface par exempleIPlainTextable
    • Faire l'interface appliquer une propriété booléenne appelée PlainTextMode (set false par défaut)
    • Extend TextBox et DropDownList avec vos propres contrôles qui mettent en œuvre IPlainTextable
    • Dans la section Rendu de vos WebControls étendues, rendent le texte brut value si PlainTextMode est vrai. pour votre sous-classe par exemple de TextBox

      protected override void Render(HtmlTextWriter writer) 
      { 
          if (PlainTextMode) 
           writer.WriteLine(this.Text); 
          else 
           base.Render(writer); 
      } 
      
    • Avant de rendre sur votre page, exécutez à travers tous les IPlainTextable contrôles et définissez le PlainTextMode à true.

Je l'ai écrit un peu nifty méthode pour itérer à travers un jeu de contrôle imbriqué:

public static List<T> FindControlsOfType<T>(Control ctlRoot) 
{ 
    List<T> controlsFound = new List<T>(); 

    if (typeof(T).IsInstanceOfType(ctlRoot)) 
     controlsFound.Add((T)(object)ctlRoot); 

    foreach (Control ctlTemp in ctlRoot.Controls) 
    { 
     controlsFound.AddRange(FindControlsOfType<T>(ctlTemp)); 
    } 

    return controlsFound; 
} 

donc vous suffit de faire quelque chose comme:

foreach (IPlainTextable ctl in FindControlsOfType<IPlainTextable>(this)) 
{ 
    ctl.PlainTextMode = true; 
} 

et ne votre rendu à la chaîne après que ...