ASP.NET Model Binding DropDown unbekannter Wert

Für Webforms hat sich Microsoft schon vor einigen Jahren das Model Binding einfallen lassen, das große Ähnlichkeiten zu ASP.NET MVC aufweist.

Wenn man eine Drop Down Liste einsetzen möchte, wird gleich doppelt gebunden. Der Wert in der Tabelle per SelectedValue und die Vorschlagsliste mit einem Wert und einem Schlüsselwert (key).

   1:  <asp:DropDownList ID="drpmailtext" runat="server" CssClass="form-control"
   2:     AppendDataBoundItems="true"
   3:     ItemType="System.String" SelectMethod="listtexte"
   4:     OnDatabinding="drpmailtext_DataBinding"
   5:     SelectedValue='<%#BindItem.MailText %>'>
   6:     <asp:ListItem Text="..."></asp:ListItem>
   7:  </asp:DropDownList>
 

In diesem speziellen Fall wird ein Verzeichnis am Webserver ausgelesen, bzw alle darin enthaltenen .TXT Dateien. Um den Dateinamen zu erhalten wird die Pfadliste durchlaufen und der Dateinamen mit Erweiterung extrahiert und in ein generische Liste vom Typ String gespeichert und an die DropDownliste übergeben.

   1:   Public Function listtexte() As List(Of String)
   2:          Dim liste As New List(Of String)
   3:          Dim dateien = Directory.GetFiles(
Server.MapPath("~/templates/"), "*.txt")
   4:          For Each d In dateien
   5:              liste.Add(Path.GetFileName(d))
   6:          Next
   7:          Return liste.ToList
   8:  End Function

Letztendlich soll der Benutzer im Formular einen Eintrag auswählen können. Dieser Eintrag wird natürlich auch dargestellt, wenn der Datensatz aus der Tabelle aufgerufen wird.

image

Dabei entstehen zwei Probleme:

  • Was ist wenn nichts im Feld steht (Nothing oder “”)
  • Was ist wenn im Tabellenfeld ein Wert steht, der nicht in der Vorschlagsliste vorhanden ist

Für den ersten Fall wurde in Zeile 6 im ersten Listing, einfach ein Dummy Listitem Eintrag mit “….” angelegt. Dies ist z.B. der Fall bei einem neuen Datensatz. Weil das Attribut AppendDataItem das so definiert, werden die neuen Einträge danach in die Dropdown Liste eingefügt.

image

Der eigentliche Wert definiert sich über das SelectedValue Attribut. Dieser ist gebunden an das Feld Mailtext. Mit dem Schlüsselwort BindItem eine Zwei Wege Bindung.

Genau diese Bindung erzeugt ein Problem, wenn die txt Datei fehlt, weil gelöscht. In der Datenbank gibt es noch immer Records die im Feld den Namen der Text Datei stehen haben.

Zur Laufzeit wird ein Fehler erzeugt wie

'DropDownList' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value

Man möchte per deklarativen ASPX Code den etwas zuweisen, was es nicht gibt. Ein Lösungsansatz (ich sage nicht der einzige oder einfachste) ist in den Binding Prozess des Drop Down Steuerelements einzugreifen.

   1:   OnDatabinding="drpmailtext_DataBinding"

Wenn dort das Binding fehlt schlägt und so eine Exception erzeugt, wird diese behandelt und der Wert auf den Ausgangswert in der Vorschlagsliste gesetzt. Der Eintrag mit den drei Punkten.

   1:   Protected Sub drpmailtext_DataBinding(sender As Object, e As EventArgs)
   2:     Dim drp = CType(sender, DropDownList)
   3:     Try
   4:        RemoveHandler drp.DataBinding, AddressOf drpmailtext_DataBinding
   5:        drp.DataBind()
   6:     Catch ex As Exception
   7:        drp.SelectedValue = "..."
   8:     End Try
   9:  End Sub

 

Unbedingt den Handler deaktivieren, ansonsten landet man in einer Endlosschleife.

ASP.NET Webforms Schulungen können Sie nach wie vor bei ppedv buchen.

Kommentare sind geschlossen