| 

.NET C# Java Javascript Exception

5
Hallo,

ich habe einen ASP.NET WebService der über eine Such-Funktion verschiedene Objekte zurück gibt. Der Rückgabewert ist also List(of Object) und damit in der SOAP-Welt Anytype.
Das funktioniert soweit auch ziemlich gut und mit der Lösung bin ich recht zufrieden.

Nun habe ich eine weitere Klasse hinzugefügt. Diese wird ebenfalls für die Suche verwendet. Allerdings erhalte ich bei diesem Typ nun die folgende Fehlermeldung.

System.InvalidOperationException: Der Typ ApiService.NeuesObjekt wurde nicht erwartet. Verwenden Sie das XmlInclude- oder das SoapInclude-Attribut, um Typen anzugeben, die nicht statisch sind.


Erzeuge ich nun eine Dummy Funktion die genau diese Klasse als Rückgabewert hat, kann das Objekt auch durch die Suchfunktion zurückgegeben werden.

<WebMethod()> _
Public Function Foo() As NeuesObjekt
Return New NeuesObjekt()
End Function


Es scheint also so, als wenn der WebService bemerkt, dass diese Klasse zur externen/öffentlichen Verwendung genutzt wird und sie anschließend "bekannt/öffentlich" macht. Die Fehlermeldung beschreibt das ja auch mehr oder weniger schon.
Leider hilft es auch nicht, wenn ich die Klasse NeuesObjekt mit den genannten Attributen versehe.

Daher Frage ich mich, wie ich eine Klasse im WebService (der WSDL?) bekanntmache mache, ohne das es eine Funktion gibt die diesen Typ als Rückgabewert (oder wahrscheinlich auch Parameter) hat.
13.02.2014
Slashi 409 2 8
Es würde mich mal interessieren, wie Du denn auf diese neue Klasse zugreifst, wenn ursprünglich gar keine Methode vorhanden ist, die diese Klasse im WebService erzeugt!
JEwen 13.02.2014
Wie unten von 'Maria Simlinger' richtig vermutet ist der Rückgabewert eine List(Of Object) und damit in der SOAP Definition Anytype.
Slashi 13.02.2014
1 Antwort
3
Eventuell kommst du mit dem ServiceKnownType Attribute weiter:

[ServiceKnownType(typeof(NeuesObjekt)]


Der Grund ist - vermute ich - dass dieses Objekt im Suchergebnis List<object> zurückgegeben wird, aber nirgendwo im Service explizit. Das ServiceKnownType Attribut behebt das.

In VB:

<ServiceKnownType(GetType(NeuesObjekt))>


zusätzlich zum ServiceContract Attribute verwenden.
13.02.2014
Maria Simlinger 1,1k 1 9
Ja genau ist der Grund. Wenn ich das der Dokumentation richtig entnehme, findet das Attribut nur in einem WCF Service anwendung. Dennoch habe ich einmal versucht dem WebService dieses Attribut zu geben, jedoch ohne einen Effekt.
Slashi 13.02.2014
Wie ist denn NeuesObjekt aufgebaut? Wenn du da Referenzen auf andere Objekte hast, braucht NeuesObjekt das Attribute <XmlInclude(GetType(ReferenzObjektTyp))> und evtl. das Service auch hierfür <ServiceKnownType()>.
Maria Simlinger 13.02.2014
Bzw. wenn NeuesObjekt als Referenz in einem anderen Objekt verwendet wird, bei dem anderen Objekt <XmlInclude()> für NeuesObjekt.
Maria Simlinger 13.02.2014
Bzw. ist Vererbung im Spiel?
Maria Simlinger 13.02.2014
Ja NeuesObjekt ist von BaseObject abgeleitet. Muss dieses dann auch entsprechend mit dem Attribut versehen werde?
Slashi 13.02.2014
hättest ja auch schon mal den code des objektes + basisklasse posten können. hier würde sich das erste posting eignen. dann müsste man auch nicht so viel aus der nase ziehen.
lbm1305 13.02.2014
1
Dann muss auf BaseObject das Attribut <XmlInclude(GetType(NeuesObjekt))> und auf das Service noch zusätzlich <ServiceKnownType(GetType(BaseObject))>. Das ist zwar nicht schön, weil BaseObject das für alle "Kinder" braucht, von denen es laut OO Prinzip ja nichts wissen sollte. Alternative: Auf der Methode des Web Services anbringen wie hier: http://msdn.microsoft.com/de-de/library/system.xml.serialization.xmlincludeattribute(v=vs.110).aspx
Maria Simlinger 13.02.2014
Stimmt Du hast vollkommen recht, im OO-Gedanken ist es erst einmal befremdlich. Aber: So funktioniert ist. Die Objekte werden in der WSDL bekannt gegeben. Vielen Dank!
Slashi 13.02.2014
2
Noch besser, statt WebServices, WCF Services nutzen. Da ist es dann egal ob im IIS oder sonstwo gehostet und die Definitionen (ServiceContract, DataContract) sind wesentlich besser definiert und klarer. In WCF wäre diese Klasse, definiert in der eigentlichen Liste, auf jeden Fall WSDL bekannt gewesen, ohne ServiceKnownType anzugeben.
JEwen 13.02.2014
1
@JEwen: da der Return Type List(of Object) bzw. List<object> war kommt man um ServiceKnownType auch bei WCF nicht umhin. Und im DataContract braucht es dann ein KnownType() Attribute, wenn ich recht informiert bin.
Maria Simlinger 13.02.2014
2
@Maria: Hm, das kann ich mir nicht vorstellen, dann hätte er auch das erste Objekt bereits so kennzeichnen müssen. Aber damit konnte er arbeiten, weil die Auflistung in einer WebMethode benutzt wurde. Die zweite Klasse wurde halt nie irgendwo genannt und musste daher gekennzeichnet werden. Aber egal, bei WCF wird halt sauberer definiert und daher sollte es diese Probleme nicht geben.
JEwen 13.02.2014
2
In dieser Konstellation hast du recht. In diesem Fall reicht entweder KnownType auf der Klasse oder ServiceKnownType zusätzlich zum ServiceContract. Es gibt nichtsdestotrotz Fälle in denen man beides braucht, wenn mit List<object> oder Hashtable gearbeitet wird, und auch der Basistyp in keinem ServiceContract auftaucht. Wobei mir der Sinn von List<object> nicht klar ist, zumindest den Basistyp statt object könnte man verwenden...
Maria Simlinger 13.02.2014
1
@JEwen: Zu Anfang des Projektes war WCF eine Option und auch erstrebenswert. Da hier allerdings Plattformunabhängigkeit eine große Rolle spielt, fielen WCF-Services schnell wieder raus. Demoprojekte in .NET fernen Sprachen wie PHP, JS, Java sowie cURL basierte Aufrufe auf Linuxkonsolen waren in kurzer Zeit nicht umzusetzen. Dazu kam ein erheblicher Mehraufwand für das Einlernen in die Technologie.
Slashi 14.02.2014

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH