Manchmal läuft einem beim Basteln in Visual Studio ein Problem über den Weg, das einen stundenlang beschäftigen kann. So ging es am letzten Wochenende unserem neuen Kollegen Tino Krüger mit der Exception Socketverbindung abgebrochen:
Beim Abrufen von Daten über einen WCF SOAP Web-Service wird folgende Exception ausgelöst: „Die Socketverbindung wurde abgebrochen. Dies kann durch einen Fehler beim Verarbeiten der Nachricht, durch ein Überschreiten des Empfangstimeouts durch den Remotehost oder durch ein Problem bei der zugrundeliegenden Netzwerkressource verursacht sein.“

Das kann viele Ursachen haben. Die Betrachtung der Inner-Exception „Eine vorhandene Verbindung wurde vom Remotehost geschlossen“ fördert auch keine genaueren Details zu Tage.

Als erstes schließt man die Standardprobleme, wie zum Beispiel eine gestörte Netzwerkverbindung oder ein veralteter Dienstverweis im Bezug auf das Datenmodel, aus. Bringt das keine Lösung zutage, geht die Suche los.

In unserem Fall lag die Ursache des Problems darin, dass wir Enums verwendet haben – sehen wir uns das einmal genauer an. Als Grundlage betrachten wir den in einer Klasse „Benutzer“ verwendeten Enum „Geschlecht“.

[DataContract]

public enum Geschlecht

{

[EnumMember]

Männlich = 1,

[EnumMember]

Weiblich = 2

}

[DataContract]

public class Benutzer

{

[DataMember]

public Geschlecht Geschlecht { get; set; }

}

Anhand der Definition des Enums erkennt man zwei Dinge. Zum einen, dass es nur zwei gültige Werte für das Geschlecht eines Benutzers gibt und zum anderen, dass allen Elementen des Enums Zahlenwerte zugewiesen sind.

               

Setzt man bei der Initialisierung eines Benutzer-Objektes den Wert für die Eigenschaft „Geschlecht“ nicht, wird automatisch der Standard-Wert für diese Eigenschaft gesetzt. Das ist auch die Fehlerquelle: Werden den Enum-Elementen bei der Definition keine Zahlenwerte zugeordnet, ist der Standard-Wert des Enums das erste Element des Enums. Werden den Enum-Elementen hingegen Zahlenwerte zugeordnet, ist der Standard-Wert des Enums immer Null (0). Dabei ist es egal, ob es ein Enum-Element mit diesem Wert gibt oder nicht.

In diesem Fall gibt es aber kein Enum-Element mit dem Wert Null (0). Für die Verwendung des Benutzer-Objektes bzw. dessen Eigenschaft „Geschlecht“ stellt das kein Problem dar. Ein Problem entsteht erst bei der Serialisierung der vom Web-Service gesendeten Daten an den Client. Bei der Deserialisierung des Benutzer-Objektes wird für die Eigenschaft „Geschlecht“ die Zahl Null (0) verwendet.  Bei der anschließenden Serialisierung durch den Client wird versucht den Wert Null (0) in ein gültiges Enum-Element vom Typ Geschlecht umzuwandeln. Da ein solches Element nicht existiert, wird eine Exception geworfen und der Vorgang abgebrochen. Das Ergebnis ist die zu Beginn vorgestellte Exception.

Im Prinzip gibt es für dieses Problem drei Lösungen.

  1. Sie verwenden keine Enums dessen Elementen Zahlenwerte zugewiesen wurden.
  2. Sie definieren Emuns immer so, dass in jedem Fall ein Element mit dem Zahlenwert Null (0) vorkommt
  3. Sie stellen sicher, dass der Objekt-Eigenschaft, die ein Enum verwendet, immer ein gültiges bzw. vorhandenes Element zugeordnet ist.

Geschrieben von Tino Krüger