Monday, March 23, 2009 12:50 PM
dparys
The remote server returned an error: NotFound – Häh?
Bitte nicht, ich fühle mich in das Pre-COM Zeitalter versetzt. Bei COM hatte ich immerhin noch einen Fehlercode bekommen und konnte noch kurz im Header nachschauen was es vermutlich sein könnte, doch das?
Diese Fehlermeldung hätte man auch einfach mit einem “on error resume next” verstecken können. Die bringt mir nichts. Rein gar nichts!
Was wollte ich machen? Ich schreibe gerade einen Prototyp mit ASP.NET MVC und Silverlight die direkt mit LINQ to SQL generierten Objekten arbeitet. Ist wirklich nur ein kleiner, überschaubarer Prototyp, da brauche ich keine Abstraktion der Objekte in einem Domänen Modell, dachte ich mir. Nun, hätte ich doch ein eigenes Domänen Modell geschrieben so wäre mir diese Fehlermeldung nicht untergekommen und ich hätte die 3 Stunden besser in den Code investieren können.
Der Fehler wird vom Silverlight WCF Proxy erzeugt wenn der End Callback aufgerufen wird. Anbei der Proxy Code
1: public System.Collections.ObjectModel.ObservableCollection<Liga.MatchDay.GameSvcReference.Player> EndFindAllPlayers(System.IAsyncResult result) {
2: object[] _args = new object[0];
3: System.Collections.ObjectModel.ObservableCollection<Liga.MatchDay.GameSvcReference.Player> _result = ((System.Collections.ObjectModel.ObservableCollection<Liga.MatchDay.GameSvcReference.Player>)(base.EndInvoke("FindAllPlayers", _args, result)));
4: return _result;
5: }
und hier verkürzt die Stelle die den Fehler wirft:
1: base.EndInvoke("FindAllPlayers", _args, result)
Scheint also bei der Serialisierung etwas schief zu gehen. Kurz ein zweites Projekt nachgebaut, auf das minimalste reduziert und mit der Northwind Datenbank getestet. Komisch funktioniert. Hmmm. Welche Unterschiede gibt es nun zwischen dem Repro und meinem Prototypen? Beim Repro habe ich nur eine Tabelle benutzt, ohne Relation. Also noch in das Repro eine zweite Tabelle reingezogen und siehe da, der gleiche Fehler.
Kurz recherchiert und dann habe ich auch schon das Problem gefunden. Zyklische Referenzen bei LINQ to SQL können nicht serialisiert werden. Punkt. Deshalb auch der Fehler. Ein kurzer Workaround ist nun einfach die Child Relation auf False zu setzen wie im unteren Bild:

Workaround funktioniert, für den Prototypen absolut ok.
Die Fehlermeldung die zur Laufzeit kam, ist absolut Sinnfrei. Wie gesagt, hätte ich ein eigenes Domänen Modell benutzt das ich serialisiert hätte, wäre der Fehler nie aufgetreten. Eine weitere Argumentation dürfte mein fehlendes Unit Testing im Prototypen sein. Mit Unit Tests hätte man das mitbekommen, nur was wäre der korrekte Weg für einen Unit Test gewesen? Ich meine damit nicht den Aufruf der Funktion, sondern ob man den Service wirklich zur Test Zeit hostet und so den Serialisierungsfehler bekommt oder ob man die Serialisierung manuell während des Tests anstößt, falls der zweite Prozess zum hochziehen zu viel Overhead bedeuten würde, und so das Laufzeitverhalten 1:1 abbildet.