Querdenker - das Online-Magazin mit News zum Nachdenken
Nr. 8 - April/Mai/Juni 2002 - Bedenkenswertes, Erlesenes und Quergedachtes
Linie horizontal

ASP.NET und VB.NET -
Mails versenden ohne Extra-Komponente

Wer bereits unter dem klassischen ASP mit den im IIS integrierten SMTP-Server vertraut war, wird hier bekanntes wiederfinden. Mails mit ASP zu versenden, war eine Aufgabe für CDONTS. Gleichwertiges funktioniert auch mit ASP.NET. Auch hier lassen sich für einfachste Mail-Aufgaben die eingebauten Funktionalitäten nutzen, ohne dass eine teure Extra-Komponente lizenziert werden müßte.

Automatische Mail-Generierung

Eine der zahlreichen möglichen Anwendungsfälle sind jene Stellen im Web, wo beispielsweise Info-Material, Hintergrundinfos oder eben auch Newsletter angeboten werden. Zu diesem Zweck wird meistens eine Mail- Adresse abgefragt. Um nun Mails mit ASP.NET versenden zu können, müssen die entsprechenden Klassen im .NET-Framework bemüht werden. Mail-Funktionalität wird mit dem Namensraum System.Web.Mail zur Verfügung gestellt.

System.Web.Mail ermöglicht - wie wir es von CDONTS her gewöhnt waren - den Mailversand im plain-Text-Format ebenso wie den verpönten Versand von HTML-Mails - mit und ohne Attachements. Und das Schöne daran ist einfach, dass dies alles mit verfügbaren Bordmitteln passiert. Ein installierter Internet Information Server und ein gestarteter SMTP-Server genügen - keine teuren Fremdkomponenten notwendig! Der Vorgang des Mailversendens an sich ist simpel. Für das Aussenden von personalisierten Newslettern an Tausende von Beziehern samt Mailhandling (Bouncing etc.) eignen sich spezialisierte Dienste wesentlich besser. Aber für das schnelle Mail zwischendurch genügt der eingebaute SMTP-Server vollauf.

Ein einfaches Beispiel - Text only

Für unser Beispiel sind wir von folgender beliebigen Situation ausgegangen: Auf einer Webseite wird ein Newsletter angeboten, den der User kostenfrei bestellen kann. Zu diesem Zweck ist es erforderlich, dass er eine Mailadresse angibt, an die der Newsletter versendet werden soll. In unserem Beispiel wird die Eingabe des Users zunächst auf Korrektheit (einmal wird geprüft, ob der User überhaupt irgendetwas eingegeben hat und zweitens wird mit einem regulären Ausdruck untersucht, ob die angegebene Mailadresse syntaktisch richtig sein kann). Nach der Eingabe der Mailadresse wird durch einen Button ein Click-Ereignis ausgelöst, indem automatisch eine Mail an den Seiteninhaber mit der Bitte um Erhalt des Newsletters versandt wird.

Am Rande sei noch erwähnt, dass es anerkannter Standard ist, Newsletter nur per Double Opt-In Verfahren zu versenden, d.h. sobald jemand seine Mailadresse angibt, um derartiges anzufordern, muss eine Bestätigungsmail des Anbieters versendet werden, indem der User aufgefordert wird, die Bestellung nochmals zu bestätigen, damit ein Mißbrauch seiner Mailadresse weitgehend ausgeschlossen ist. Es sollte darüber hinaus auch eine Selbstverständlichkeit sein, dass der User auch mühelos seine einmal getroffene Entscheidung rückgängig machen kann, und den Newsletter problemlos abbestellen kann. Sehen wir uns nun einmal den Quellcode an, fein säuberlich getrennt von Design- und Logik per Code Behind-Technik. Zunächst den HTML-Teil, der Einfachheit halber als WebForm1.aspx belassen und dann den eigentlichen "Maillogik-Teil", WebForm1.aspx.vb:

WebForm1.aspx

    
<%@ Page Language="vb" AutoEventWireup="false" 
     Codebehind="WebForm1.aspx.vb" Inherits="Mailversand2.WebForm1"%>
<%@ Import Namespace="System.Web.Mail" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>WebForm1</title>
	<meta content="Microsoft Visual Studio.NET 7.0" name="GENERATOR">
	<meta content="Visual Basic 7.0" name="CODE_LANGUAGE">
	<meta content="JavaScript" name="vs_defaultClientScript">
	<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
</HEAD>
<body bgColor="#ffffcc" MS_POSITIONING="GridLayout">
	<form id="Form1" method="post" runat="server">
		<asp:label id="Label1" 
		    style="Z-INDEX: 101; LEFT: 25px; POSITION: absolute; 
		    TOP: 47px" runat="server" Width="152px" 
		    Height="26px" BackColor="#FFC080" 
		    Font-Bold="True" Font-Names="Helvetica" Font-Size="Larger" 
		    Font-Underline="True">Unser Newsletter
		</asp:label>
		<asp:label id="Label3" style="Z-INDEX: 103; LEFT: 25px; POSITION: absolute; 
		    TOP: 74px" runat="server" Width="505px" 
		    Height="45px" BackColor="#FFC080" Font-Names="Helvetica" 
		    Font-Size="X-Small">Sie erhalten unseren Newsletter per Double Opt-In Verfahren. 
		    Um den einmal im Monat erscheinenden Newsletter jetzt zu erhalten, benötigen wir noch 
		    Ihre Mailadresse zum Versand. Nach Eingang Ihrer Anforderungsmail erhalten Sie von uns eine 
		    Bestätigung!
		</asp:label>
		<asp:label id="Label2" style="Z-INDEX: 102; LEFT: 25px; POSITION: absolute; 
		    TOP: 141px" runat="server" Width="117px" 
		    BackColor="#FFC080" Font-Names="Helvetica" 
		    Font-Size="X-Small">Ihre Mailadresse:
		</asp:label>
		<asp:textbox id="TextBox1" style="Z-INDEX: 104; LEFT: 171px; POSITION: absolute; 
		    TOP: 137px" runat="server" Width="199px" BackColor="#FFC080" 
		    Font-Names="Courier New" BorderColor="#FF8080" 
		    BorderStyle="Inset">
		</asp:textbox>
		<asp:regularexpressionvalidator id="RegularExpressionValidator1" style="Z-INDEX: 105; 
		    LEFT: 383px; POSITION: absolute; TOP: 140px" runat="server" 
		    BackColor="Blue" Font-Names="Helvetica" Font-Size="X-Small" 
		    ErrorMessage="Keine korrekte Mailadresse!" ControlToValidate="TextBox1" 
		    ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">
		</asp:regularexpressionvalidator>
		<asp:button id="Button1" style="Z-INDEX: 106; LEFT: 196px; POSITION: absolute; 
		    TOP: 187px" runat="server" Width="155px" 
		    Text="Newsletter anfordern">
		</asp:button>
		<asp:RequiredFieldValidator id="RequiredFieldValidator1" style="Z-INDEX: 107; 
		    LEFT: 384px; POSITION: absolute; TOP: 188px" runat="server" 
		    Width="159px" BackColor="Blue" Font-Names="Helvetica" 
		    Font-Size="X-Small" ErrorMessage="Sie haben keine Mailadresse angegeben!" 
		    ControlToValidate="TextBox1">
		</asp:RequiredFieldValidator>
		<asp:Label id="Label4" style="Z-INDEX: 108; LEFT: 30px; 
		    POSITION: absolute; TOP: 250px" runat="server" Width="493px" 
		    Height="63px" BackColor="#FFFF80" Font-Names="Helvetica" 
		    Font-Size="Larger">
		</asp:Label>
	</form>
</body>
</HTML>
    

Wir ersehen an diesem Beispiel, dass die einzelnen Elemente der Seite mittels WebForm-Generator von Visual Studio.NET einfach aus der Toolbox zusammen getragen wurden. Da wären zunächst einmal vier Label-Elemente, wobei nur das Label-Steuerelement mit der ID "Label4" zur dynamischen Anzeige von Text genutzt wird. Label4 dient dazu, dem User eine Erfolgsmeldung - oder eben das Gegenteil - eine Fehlermeldung zu präsentieren.

Zentrales Element für die User-Eingabe ist natürlich die TextBox, deren Inhalt dann im WebForm1.aspx.vb- Teil ausgewertet und weiterverwendet wird. Auffällig werden dann noch zwei Validation-Steuerelemente verwendet, der Regular Expression Validator zur Überprüfung auf eine gewisse logische Korrektheit der Mailadresse (= @-Zeichen, . als Trenner enthalten etc.) sowie das Required Field Validator-Steuerelement zur Überprüfung, ob das TextBox-Feld nicht überhaupt leer geblieben ist. Macht der User diesbezüglich einen Fehler, so wird ihm automatisch die zugehörige Fehlermeldung präsentiert und es wird keine weitere Aktion ausgelöst.

Screenshot von WebForm1.aspx mit Erfolgsmeldung

Im nun folgenden Code Behind-Teil, WebForm1.aspx.vb, wird am Ende der Button_Click-Event ausgewertet, die Anforderungsmail des Newsletters an den Herausgeber versandt und im gleichen Atemzug ein Bestätigungsmail an den User generiert. Gleichzeitig wird in das Steuerelement Label4 dynamisch eine Vollzugsmeldung geschrieben bzw. bei Nichtdurchführung des Mailversands eine Fehlermeldung ausgegeben. Ermöglicht wird dies durch die statische Methode SmtpMail.Send mit den vier Parametern Absender, Empfänger, Betreff und eigentlicher Inhalt des Mails.

WebForm1.aspx.vb

	
Imports System.Web.Mail

Public Class WebForm1
    Inherits System.Web.UI.Page
    Protected WithEvents Label3 As System.Web.UI.WebControls.Label
    Protected WithEvents Label2 As System.Web.UI.WebControls.Label
    Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox
    Protected WithEvents RegularExpressionValidator1 As _
       System.Web.UI.WebControls.RegularExpressionValidator
    Protected WithEvents Button1 As System.Web.UI.WebControls.Button
    Protected WithEvents RequiredFieldValidator1 As _
       System.Web.UI.WebControls.RequiredFieldValidator
    Protected WithEvents Label4 As System.Web.UI.WebControls.Label
    Protected WithEvents Label1 As System.Web.UI.WebControls.Label

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub

    Private Sub Page_Init(ByVal sender As System.Object, _
           ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

    Private Sub Page_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, _
           ByVal e As System.EventArgs) Handles Button1.Click
        Dim strAbs, strEmpf, strTitel, strAbs2, strEmpf2, strTitel2 As String
        strAbs = Me.TextBox1.Text.ToString
        strEmpf = "newsletter@see-programming.at"
        strTitel = "Newsletter-Anforderung"
        strAbs2 = "newsletter@see-programming.at"
        strEmpf2 = Me.TextBox1.Text.ToString
        strTitel2 = "Ihre Newsletter-Anforderung"
        Try
            SmtpMail.Send(strAbs, strEmpf, strTitel, "Ich/Wir bestellen Ihren Newsletter")
            SmtpMail.Send(strAbs2, strEmpf2, strTitel2, _
                "Vielen Dank für Ihre Newsletter-Anforderung! " & _
                "Bitte bestätigen Sie dieses Mail, indem Sie dieses Mail einfach retournieren")
            Label4.Text = "Newsletter-Anforderung wurde versendet!"
        Catch ex As Exception
            Label4.Text = "Fehler aufgetreten: " & ex.Message.ToString
        End Try
    End Sub
End Class
	

Als Beispiel für die an den Seitenbetreiber generierte Mail:

Screenshot des Mails

Als Nachteil des SMTP-Servers stellt sich leider auch heraus, dass es nicht möglich ist, gescheiterte Mailzustellungen bzw. einen fehlerhaften Mailversand wirklich abzufangen. Jedes generierte Mail wird in den Pickup-Ordner des mailroot-Verzeichnisses des IIS verschoben und erst von dort wird sie vom SMTP-Service gelesen und versendet. Scheitert jetzt der Versand - egal aus welchen Gründen - landen die Mails im Badmail- Folder und ruhen dort selig. Dies bedeutet auch, dass der entsprechende Try-Catch-Block im vb-File nur Exceptions der Applikation selber abfängt, ungeachtet dessen, ob es auch tatsächlich zum erfolgreichen Mail-Versand kommt.

HTML-Mails und Attachments

Es sei hier nur der Vollständigkeit halber erwähnt: Unverlangt zugesandte Mails im HTML-Format sind eine Zumutung, keineswegs standardkonform und auch für zahlreiche Mailprogramme eine unüberwindliche Hürde (Stichwort: T-Online-Mailer, AOL etc.) Mails im HTML-Format sollten eigentlich nur im Intranet verwendet werden, wo von einer Monokultur der Mailprogramme ausgegangen werden kann. Verstehen Sie uns mit dieser persönlichen Anschauung nicht falsch: In Zeiten der dauernden Security Holes kann eine HTML-Mail mit integriertem bösartigem VBScript schon das Aus für das Netzwerk sein und obendrein ist wohl nichts störender als ein HTML-Mail mit einem Haufen integrierter Bilder, welche letztendlich offline gelesen werden. Lesbarkeitswert und Informationsmehrwert des Mails: Null!

Um also HTML-Mails versenden zu können benötigt man die Methoden der Klasse MailMessage. Ergänzen bzw. ersetzen wir also obigen Button_Click-Event um folgende Zeilen:

Private Sub Button1_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button1.Click
    Dim meineMail As New MailMessage    
    Dim strInhalt As String
        
    meineMail.From = Me.TextBox1.Text.ToString
    meineMail.To = "newsletter@see-programming.at"
    meineMail.Subject = "Newsletter-Anforderung"
    
    meineMail.BodyFormat = MailFormat.Html
    strInhalt = "<html><body><h1>Bestellung Ihres Newsletters</h1></body></html>"
    meineMail.Body = strInhalt
        Try
            SmtpMail.Send(meineMail)
            Label4.Text = "Newsletter-Anforderung wurde versendet!"
        Catch ex As Exception
            Label4.Text = "Fehler aufgetreten: " & ex.Message.ToString
        End Try
End Sub
    

Aus Gründen der Übersichtlichkeit wurde hier auf den gleichzeitigen Versand einer zweiten Mail verzichtet. Um hoffentlich nicht zweifelhafte Attachments zu versenden genügt das Hinzufügen einer einzigen Zeile zu obigem Code:

    meineMail.Attachements.Add(New MailAttachment("c:\IhrPfad\Beispiel.txt"))
    

Dies ist eine relative bequeme Art mehr oder weniger brauchbare Anhängsel zu einer Mail zu versenden. Die MailMessage-Klasse kennt natürlich noch eine Reihe weiterer Methoden und Properties, etwa zur Einstellung des Enconding-Typs (BodyEncoding) und auch Möglichkeiten zur Beeinflussung des Mail-Headers. Dies würde hier aber zu weit führen.

HTML-Formatierung einer per MailMessage-Klasse definierten Mail

In der nächsten Ausgabe von querdenker:

Weitere .NET-Artikel: Achtung - englischsprachiges Service Pack 1 steht zum Download bereit!
...und vieles mehr ...ab Juli 2002

Buchtip in eigener Sache -
VB.NET - die Migration

Ausnahmsweise machen wir auch einmal Werbung in eigener Sache. Unser Team-Mitglied, Martin Kratschmer, hat ein Buch verfasst, welches im Verlag moderne Industrie/Bonn erschienen ist: "VB.NET - die Migration" (ISBN 3-8266-0843-7), behandelt auf etwa 500 Seiten jenes Kernthema, das Visual Basic-Programmierer in der nächsten Zeit mit Sicherheit freiwillig oder unfreiwillig beschäftigen wird: Wie bringe ich meine VB6-Applikationen erfolgreich in die "neue" .NET-Zeit?

Die drängenden Fragen des VB-Programmierers werden darin behandelt:Buchumschlagvon VB.NET-Die Migration

  • Muss ich auf VB.NET migrieren?
  • Wann lohnt es sich, meine Applikation umzustellen?
  • Wie muss ich VB6-Anwendungen vorbereiten?
  • Welche Änderungen gibt es in VB.NET gegenüber VB6?
  • Was ist mit den Windows Forms?
  • Kann ich meine Steuerelemente weiterverwenden?
  • Was ist mit den entsprechenden Methoden und Eigenschaften?
  • Mein Steuerelement gibt es in VB.NET nicht mehr, was verwende ich jetzt?
  • Was kann der "Upgrade Wizard" automatisch erledigen, was muss manuell gemacht werden?
  • Wie löse ich jene Migrationsprobleme, die der Aktualisierungsassistent nicht schafft?
  • Was sind die "Kompatibilitätsklassen" ?
  • Was sind die Unterschiede im Visual Studio.NET?
  • Welche Tools gibt es, die mir beim Testen und Analysieren von VB.NET helfen?
  • Welche neuen Techniken sind in VB.NET enthalten?
  • Das Buch eignet sich gleichermassen für den Profi und für den Einsteiger, da auch Einführungen in das .NET-Framework (Unterkapitel zu ASP.NET, ADO.NET) und auch zahlreiche Klassen und Namensräume besprochen werden.

    Schritt für Schritt-Anleitungen, viele Grafiken und letztendlich auch der Quellcode auf enthaltener CD-ROM sollen nicht nur dem langjährigen VB-Entwickler, sondern auch dem nicht so erfahrenen Programmierer helfen, anfallende Migrationsarbeiten zügig und erfolgreich zu bewältigen.

    Aufgrund der vielen enthaltenen Tabellen (Übersichten zu Namensräume/Klassen/Controls/Methoden/ Properties zwischen VB6 und VB.NET) erscheint "VB.NET - Die Migration" auch als Nachschlagewerk für die schnelle Migration von VB6 auf VB.NET geeignet. Checklisten, die das Besprochene nochmals zusammenfassen und dem Entwickler an der Hand nehmen bei der Abarbeitung der Migrationsarbeiten runden das Buch ab.

    "VB.NET - die Migration" kostet moderate runde 35 Euro, erscheint um den 18. April 2002 und ist in zahlreichen Fachbuchhandlungen sowie auch über das Internet, beispielsweise direkt beim Verlag mitp.de oder bei Amazon, erhältlich.

    VB.NET - die Migration

    Hammer 1

    Meine Meinung -
    Nabelbeschau

    Wie ist die werte Befindlichkeit? Wie ist Ihre Meinung zu Microsofts .NET? Angst vor Passport? Diese etwas seltsame Einleitung soll zu einer Art Nabelbeschau überführen, die ich mir diesmal aus gegebenem Anlass erlaube. Sie haben sicherlich bemerkt, dass sich die Ausrichtung unseres Magazins geradezu drastisch verändert hat. Jede Ausgabe ist durchdrungen von einigen .NET-Artikeln, Java oder PHP beispielsweise kommen kaum mehr vor. Warum? Seit dem Erscheinen der Beta 1 des Framework SDKs und von Visual Studio.NET hat sich auch der Fokus unserer Firma geradezu dramatisch verändert und das Augenmerk liegt heute fast ausschließlich auf den Microsoft- Plattformen.

    Hammer 2


    Durch die Konzentration auf die dazugehörigen Techniken für Inter- und Intranet, wie ASP, ASP.NET, VB, VB.NET, manchmal auch C# hat sich auch der Fokus von "querdenker" mitverändert. Diese markanten Veränderungen rufen natürlich auch nach einer angepassten Ausrichtung unseres Auftritts im Internet. Sprich: Im Laufe des Jahres wird ein Relaunch der bestehenden Seiten und auch des Magazins erfolgen, ebenso wie eine Übersiedlung auf .NET-gepowerte Server-Technologie. Damit wird auch mehr Interaktion und Nutzen für den User einhergehen. Zu Verbessern gibt es einiges, nicht zuletzt, ist die derzeitige Ausrichtung vom Layout her auf eine Bildschirmauflösung von 1280x1024 Pixel ausgerichtet, was eine gewisse Flexibilität vermissen lässt. Nicht verändern, sondern erweitern wird sich die Artikelausrichtung. Lassen Sie sich überraschen und bleiben Sie uns gewogen. Alles ist im Fluss...

    Leider übermannt uns diese "Nabelbeschau" in wirklich aufregenden Zeiten: Es vergeht leider keine Woche seit dem 11. September 2001, in der Berufene und weniger Berufene nicht neue-alte Ideen zur besseren Überwachung und Einschränkung der Informationsfreiheit des Internets ausbrüten. Eines bleibt jedoch immer gleich bei diesen mehr oder weniger kruden Ideen: Sie sind allesamt unverhältnismäßig, unwirksam und nur für den Super-DAU abschreckend. Den Vogel des Monats in dieser Richtung hat diesmal Herr Jürgen Büssow, seines Zeichens Regierungspräsident in Düsseldorf, mit seiner Provider-Sperrverfügung abgeschossen.

    Dieser Testballon für spätere, weitere Sperrungen hat zahlreiche Reaktionen provoziert. Die Story und Hintergründe zu dieser regierungsseitigen Provokation und schließlich die provozierte Strafanzeige gegen Mitglieder der Regionalregierung sowie einige Provider finden Sie hier - Odem.org. Offenbar hat der Begriff "Regionalregierung" doch größere Nähe zum Begriff "Provinz" bzw. "provinziell" als uns lieb sein kann.

    Der bereits mehrfach an dieser Stelle erwähnte Alvar Freude hat mit seiner Reaktion auf die Sperrungsverfügung wieder einmal großen Mut bewiesen, der unserer Meinung nach unterstützt gehört. Denn es kann nicht angehen, dass mißliebige Seiten einfach ausgeblendet werden - egal, ob sie von links oder rechts oder von sonstwoher stammen. Noch dazu, wo derartige Sperren von wenig Versierten leicht ausgehebelt werden können und jedermann auch ein Recht darauf hat, sich über diversen Nazi-Dreck oder sonstigen Müll sein eigenes Bild zu machen. Noch dazu, wo man mit dieser scheinbaren Ausblendung von nicht genehmen "Inhalten" niemanden davon überzeugen kann, "nationalem Gedankengut" abzuschwören. Offenbar ist diese Büssowsche Verfügung ein geradezu klassischer Fall von Verwechslung von Ursache und Wirkung. Meint: Wenn wir erst die Auswirkungen beseitigen, ist auch das Symptom weg? Typisch Politiker halt - möchte man meinen, aber: Informationsfreiheit ist unteilbar - meiner Meinung nach.

    Am Rande sei auch noch eine neue Rubrik auf unseren Seiten erwähnt, die sich um Satire dreht und keinen Anspruch auf Ernsthaftigkeit erhebt - also nicht unbedingt mit Programmierung und IT zu tun hat. Diesmal beschäftigen wir uns mit einer mittlerweile lieb gewordenen "Versandfirma", die uns tagtäglich mit neuen Gewinnversprechungen und überaus interessanten Produkten erheitert und auch - erfreut. Dieses lustige "Unternehmen" hat es sich durch täglich bewiesene Kreativität verdient, einen breiteren Bekanntenkreis zu erlangen. Klicken Sie mal auf "Satire" und schmunzeln Sie...

    Martin Kratschmer

    Hammer 3

    see-programming

    Home
    Programmierung
    Philosophie
    Referenzen und Projekte
    Kontakt
    Newsletter

    querdenker

    Frühere Ausgaben

    Impressionen - aus den Tiefen des Netzes

    Satire

    Impressum
    Haftungsausschluss
    Linie horizontal