Laden...

Webservice in eigenem Control verwenden

Erstellt von typhos vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.754 Views
T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren
Webservice in eigenem Control verwenden

Hallo,
ich habe einen Webservice geschrieben. Dieser stellt zum Beispiel über eine Methode eine Liste von Anreden bereit. Dabei kommt ein eigener Typ Anrede zum Einsatz. Dieser Typ wird ja dann auch in die wsdl-Datei eingetragen.
Wenn ich den Webservice dann als Webverweis in eine Webseite einbinde (unter dem Namespace MeinWebservice), dann steht der Typ Anrede ja auch auf der Webseite als MeinWebservice.Anrede zur Verfügung.

So weit, so gut...

Nun habe ich ein neues Projekt erstellt, in dem ich ein eigenes Control, abgeleitet von DropDownList, erstellt habe: ComboBoxAnrede. Die Klasse liegt im Namespace MeineControls.
In dieses Projekt habe ich den Webservice wiederum als Webverweis hinzugefügt. Hier bekommt der Webservice den Namespace MeineControls.Webservice.
Nun kann ich über oben angesprochene Methode alle Anreden ermitteln und die DropDownList befüllen.

Klappt auch wunderbar.

Nach dieser langen Vorgeschichte nun zu meinem Problem:
Ich habe in meiner ComboBoxAnrede auch eine Methode, um Einträge (Anreden) hinzuzufügen. Diese nimmt als Parameter natürlich ein Objekt vom Typ Anrede. Wenn ich nun von der Webseite (in die ich übrigens das Control eingebunden habe) eine Anrede zur DropDownList hinzufügen will, bekomme ich eine InvalidCastException, da der referenzierte Webservice in der Webseite und im Control unterschiedliche Namespaces haben und als unterschiedliche Typen behandelt werden:
MeinWebservice.Anrede kann nicht in MeineControls.Webservice.Anrede konvertiert werden

Genau genommen sind es ja aber dieselben Typen. Beide "stammen" von der Klasse Anrede in meinem Webservice ab und haben damit die gleichen Member usw.

Gibt es denn eine Möglichkeit, wie man dieses Problem lösen kann? Ich meine, ich finde die Typsicherheit von .NET ja prima, aber das hier geht mir zu weit.
Würde mich wirklich freuen, wenn jemand einen Tipp oder eine Alternative für mich hat...

Vielen Dank schon mal!

S
1.047 Beiträge seit 2005
vor 17 Jahren

lager deinen typen in eine eigene assembly (dll) aus und referenziere in beiden projekten (webservice und client) darauf

MeinWebservice.Anrede ist ja auch ein anderer typ als MeineControls.Webservice.Anrede

nur weil die typen gleich heißen, sind sie es aber nicht
du hast z.b. verschiedene namespaces und die gehören zur identifikation dazu 😉

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Hi und Danke für die Antwort!

Ich habe auch schon versucht, den Typ in eine eigene Assembly auszulagern und habe diese in der webseite sowie im Control referenziert. Das Problem bleibt aber bestehen.
Denn der Typ wird ja in die wsdl-Datei eingetragen und die Methode vom Webservice liefert auf der Webseite den Typ MeinWebservice.Anrede, obwohl ich im Webservice die Methode so deklariert habe, dass der Typ ExtraAssemblyNameSpace.Anrede zurückgegeben wird. Der Typ wird einfach als complexType in die WSDL-Datei eingetragen und auf der Webseite wird nur der benutzt. Also habe ich wieder das Problem beim Befüllen der ComboBox:

MeinWebservice.Anrede kann nicht in ExtraAssemblyNameSpace.Anrede konvertiert werden

Ich bin am Verzweifeln... 🙁

S
1.047 Beiträge seit 2005
vor 17 Jahren

ok, hab grad mal gegooglet... so einfach wie mit den assemblies geht das dann doch nicht^^

ok ich mach mich mal kundig...

laut diesen beitrag mußt du noch paar angaben machen

nachtrag:
hab noch das hier ausgegraben 🙂

nachtrag2:
auch im forum gibts dazu schon was
post 2 WS komplexen Datentyp-Array darstellen

nachtrag3:
http://www.codeproject.com/useritems/GetObjectFromWebservice.asp
http://www.microsoft.com/belux/msdn/nl/community/columns/jdruyts/wsproxy.mspx

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Erstmal vielen Dank für Deinen Einsatz!

Leider bekomme ich es aber einfach nicht hin. Den Artikel bei codeproject habe ich auch vorher schon gelesen und das funktioniert auch. Aber leider nur bei "richtigen" Anwendungen. Bei Webreferenzen in Webseiten gibt es ja keine reference.cs, sondern nur eine WSDL-Datei, also hilft mir das dort nicht weiter.

Die anderen Links habe ich auch alle durchforstet, aber entweder bin ich zu blöd, das dort genannte umzusetzen oder.... ich weiß auch nicht. Ich krieg es einfach nicht hin X(

S
1.047 Beiträge seit 2005
vor 17 Jahren

hm, muß ich mal selbst probieren... hab sonst net soviel mit webservices zu tun^^

also hast du den webservice nicht als reference hinzugefügt?
wie machst man das nur über wsdl?

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Na ja, wenn man zu einer Webseite einen Webverweis hinzufügt, wird halt keine reference.cs erzeugt. Es werden dort nur 3 Dateien angelegt (*.disco, *.discomap, *.wsdl) - mehr nicht.
Anders bei richtigen Assemblies, dort wird unter anderem immer eine reference.cs angelegt, in der man schön herumpfuschen kann 😉

Bin schon den ganzen Tag am Suchen und Probieren, aber bisher noch keine Lösung 😭

S
1.047 Beiträge seit 2005
vor 17 Jahren

hm, also ich hab nen webservice erzeugt udn ein consolenprojekt... wenn ich bei consolenprojekt einen webverweis hinzufüge und dort auf adresse von meinem webservice geht, find ich dann im ordner Reference.cs, Reference.map und Service.wsdl

nachtrag:
hab das jetzt auch mit eigenem typen ausprobiert... kam der castfehler beim compilieren, also hab ich reference.cs geändert:
hab auch eine bibliothek mit typ Anrede

in reference.cs hab ich die classe Anrede entfernt und oben das using für meine assembly die Anrede enthält eingefügt... damit klappt das dann auch

aber so richtig toll find ich diesen lösungsweg nicht...

nachtrag:
ok, wenn man den artikel von meinem letzten link nimmt kann man das sehr flexibel machen womit man gut arbeiten kann 🙂

p.s. ich arbeite mit .net 2.0 hast du vielleicht 1.1?

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Nee, ich benutze auch 2.0. Und wie ich schon schrieb funktioniert das ja auch, wie Du es gemacht hast. Aber eben nur bei Assemblies (also Konsolenanwendung, DLL etc.). Wenn Du jetzt aber in VS mal eine neue Webseite anlegst und dort einen Webverweis auf den Webservice hinzufügst, wird dort keine reference.cs angelegt, sondern nur 3 Dateien (wie ich oben schon geschrieben hab). Und daher kann ich das so leider nicht lösen.

Probier's mal aus...

S
1.047 Beiträge seit 2005
vor 17 Jahren

hm... ok jetzt seh ich was du meinst... und jetzt weiß ich auch was der eine im artikel meinte im bezug auf probleme mit asp.net

Note, however, that this approach will not always work very well with the new compilation model in ASP.NET 2.0. The actual generation of the Web Service proxy classes will be delayed until runtime, which means that the "Add Web Reference" dialog will only download the WSDL file without generating the proxies. If you wish to make use of a Schema Importer Extension in web scenarios, this means that it must be registered on the web server. Another, perhaps more suitable option, is to pre-compile the entire web site before moving it onto the production server, which also increases performance and security. Installing the Schema Importer Extension on the developers' machines and on the build server should then suffice to make use of its advantages.

schau dir mal meinen letzten link genau an

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Diese SchemaImporterExtension habe ich mir auch schon angesehen und schon ausprobiert. Aber irgendwie will es nicht.
Evtl. hapert's auch nur daran, dass die ImpoerterExtesion in den GAC muss - das möchte ich nicht.

Aber mal von einer anderen Seite betrachtet: Ich muss ja nicht unbedingt den "richtigen" Typ haben, es würde mir genügen, wenn ich den serialisierten (und dann deserialisierten) Typ, der in der WSDL-Datei angelegt wird, auch in mein Control (DropDownList) bekomme. Kann ich vielleicht die WSDL-Datei der Webseite irgendwie in das Projekt mit den Controls "importieren"? Also so, dass Control und Webseite die gleiche Webservice-Referenz/WSDL-Datei nutzen?

S
1.047 Beiträge seit 2005
vor 17 Jahren

also ich hab das mit der env.exe.config und privateassemblies ordner gemacht und es funktioniert... allerdings nicht bei dem asp.net projekt o.O

naja du kannst ja den typen vom webservice nutzen... bei mir wäre das localhost.Anrede
der sollte auch in den projekten zur verfügung stehen die dein webservice eingebunden haben

problem ist halt das er nur aus daten besteht, und keine methoden mehr enthält...

bei dem adventureworkscinema projekt hatten die das auch mit webservice realisiert
dort haben sie das so gemacht das sie nur datatables austauschen und dann auf dem client entsprechend objekte ihrer eigene nklassen erzeugt haben... wäre ja auch noch ne möglichkeit oder?

nachtrag:
wenn ich webseite veröffenltiche mache hat er es auch ohne zu mucken compiliert... allerdings kann ich das nicht testen da ich keinen iis habe und nicht weiß wie ich das ohne ihn einbinde o.O

wenn ihc mir den code aber mit reflector anschaue hat er zwar den typen aus der wsdl erstellt, aber als xml-schema den namen vom custom tpye genommen der in der extra dll liegt...

nachtrag2:
ok, nachdem ich xsp mal zum testen ran gezogen hab, mußt ich fest stellen das es immenroch net funktioniert 🙁
also da es bei der consolenaplikation geklappt hat, würd ich den weg gehen die webserviceaufrufe in eigen eigen dll zu packen... da diese compiliert wird und dabei die im link genannte version funktioniert...

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Danke für Deine Mühe!
Ja, das Auslagern der Webservice-Aufrufe in eine eigene DLL wäre auch noch möglich - stimmt! Daran habe ich noch gar nicht gedacht.

problem ist halt das er nur aus daten besteht, und keine methoden mehr enthält...

Methoden brauche ich auch nicht, nur die Daten.

Mal sehen, vielleicht lagere ich die Webservice-Aufrufe wirklich in eine DLL aus... oder ich übertrage auch nur noch DataTables oder so was...

Vielen Dank nochmal für Deine Mühe und Hilfe!

S
1.047 Beiträge seit 2005
vor 17 Jahren

also wenn es dir wirklich nur um die daten geht, dann geht das problemlos

in deiner wsdl datei ist ja die typdefinition drin, sprich wenn dein webservice auf localhost liegen würde und die webreference dahin hast, dann hast du unter localhost.Anrede diesen typen

der webservice gibt dir also sozusagen seine custom types mit, allerdings haben die halt keine methoden... aber wenn man die net brauch... =)

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Ja, schon klar. Aber es sind ja trotzdem unterschiedliche Typen, wenn ich den Webservice einmal per Webreferenz in die Webseite einbinde und einmal in mein Control, oder nicht?
In meiner Webseite liegt die Webreferenz auf den Webservice im Verzeichnis "App_WebReferences/Webservice", damit hat mein Typ den vollen Namen "Webservice.MeinTyp".
In meinem Control füge ich den Webservice ebenfalls über eine Webreferenz hinzu und ich packe den - sagen wir einfach mal - auch in einen Ordner "Webservice". So, hier hat mein Typ aber den vollen Namen "MeinControlNameSpace.Webservice.MeinTyp".
Und damit sind die Typen (trotz gleichen Inhalts) doch unterschiedlich.

Oder meinst Du das evtl. anders?

S
1.047 Beiträge seit 2005
vor 17 Jahren

die fehlermeldung oben sagt ja

MeinWebservice.Anrede kann nicht in MeineControls.Webservice.Anrede konvertiert werden

nutz einfach MeinWebservice.Anrede denn der Typ steht dir lokal auf jeden Fall zur verfügung, da er durch die wsdl definiert wird
und die bekommt jedes projekt die den webservice konsumieren möchte =)

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Hmm, hast Du das mal ausprobiert? Ich glaube nicht, dass das funktioniert (oder ich bin wirklich zu blöd dazu).
In meinem Control (das ist also eine eigenständige DLL!) habe ich doch den Namespace "MeinWebservice" gar nicht zur Verfügung. Dort ist ja nur "MeineControls.Webservice" bekannt.
Und beim Hinzufügen eines Webverweises wird doch eine neue WSDL erzeugt. Oder meinst Du, ich sollte die WSDL aus der Webseite in mein Controls-Projekt kopieren? Geht das denn? Die würde doch jedesmal beim Kompilieren überschrieben werden 🤔

S
1.047 Beiträge seit 2005
vor 17 Jahren

wenn du deinem projekt eine referenz zu einem webservice hinzufügst, macht visual studio von ganz allein das hinzufügen der wsdl datei zu deinem projekt
d.h. er läd die wsdl datei runter! darum mußt du auch immer wenn du deinen webservice änderst, den webverweis aktualisieren.

ja ich hab das ausprobiert, bei mir geht das auch... probier du es mal aus. du hast ja die probleme 😉

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Original von sheitman
ja ich hab das ausprobiert, bei mir geht das auch... probier du es mal aus. du hast ja die probleme 😉

Hab ich ja, aber - wie gesagt - funktioniert es bei mir nicht.

Also...
Ich habe meiner Webseite einen Webverweis auf den Webservice hinzugefügt. Dadurch wird eine WSDL-Datei erzeugt. Die drei angelegten Datei (*.wsdl, *.disco, *.discomap) liegen im Verzeichnis "App_WebReferences/MeinWebservice".
Im Webservice selbst habe ich eine Methode, die den Typ "ExterneLib.MeinTyp" zurückgibt. Wenn ich diese Methode aufrufe, bekomme ich natürlich nicht den Typ "ExterneLib.MeinTyp", sondern "MeinWebservice.MeinTyp", da dieser ja in der WSDL angelegt wurde.

So...
Nun habe ich ein weiteres Projekt, eine ClassLibrary (DLL) mit meinen Controls. Alle Klassen in dieser Lib sind im Namespace "MeineControls". Nun füge ich hier ebenfalls einen Webverweis auf den Webservice hinzu. Dann wird hier z.B. die schon erwähnt reference.cs und der ganze andere Kram angelegt. Dem Webverweis weise ich nun einen Namespace wie z.B. "Webservice" zu.
Nun habe ich aber nicht den Typ "ExterneLib.MeinTyp" oder - was auch noch passabel wäre - den Typ "MeinWebservice.MeinTyp", sondern ich habe hier nur den Typ "MeineControls.Webservice.MeinTyp".
Und ich kann halt nicht MeineControls.Webservice.MeinTyp in MeinWebservice.MeinTyp oder ExterneLib.MeinTyp konvertieren.

Also wie hast Du es denn gemacht, dass es bei Dir funktioniert 8o

S
1.047 Beiträge seit 2005
vor 17 Jahren

hm, unsere projekte sind etwas verschieden scheint mir.

ich hab insgesammt 4 projekte

  • webservice, referenziert eigene dll

  • webseite, referenziert webservice und eigene dll

  • eigene dll, enthält meinen custom type

  • consolen anwendung, referenziert webservice und eigene dll

soooo

kommen wir erstmal zu dem fall mit dem custom typen:
ich bekomm standardmäßig die gleichen fehler wie du, da die typen nicht konvertiert werden können
wenn ich die schritte mache wie oben vom letzutn link, läuft mein consolenprogramm, zusammen mit webservice und eigener dll
soll heißen ich bekomm auch den typen aus meiner dll von der webmethode zurück

beim websetien projekt geht es nicht...

kommen wir jetz mal zu dem fall ohne custom type:
da geht bei mir sowohl console als auch asp.net

wie schon gesagt stecken in der wsdl datei alle definitionen die benötigt werden

mein webservice liegt auf localhost und ich kann dadurchauf einen namespace localhost zugreifen wo mein "custom type" drin liegt
"" da er nur so heißt, aber halt ohne methoden ist
der entspricht auch dem rückgabetyp meiner methode
dass alles aufgrund der wsdl
es funktioniert also "localhost.Anrede a = service.GetAnrede();"

wenn ich das richtig sehe ist nun der unterschied das du ein webprojekt hast mit verweis auf den webservice und eine eigene dll mit einem control was auf dem webservice verweist und du möchtest die Anrede vom webprojekt nun in der eigenen dll benutzen, richtig?
und da knallts... was ja leider auch wieder total verständlich ist...

dadurch das du den webservice an 2 orten wieder eingebunden hast gibt es 2x den typ wieder, die funktionieren aber nicht miteinander

ich würde dir empfehlen das jetzt so zu machen das du dir eine dll baust die mit dem webservice kommuniziert... dann hat diese auch nur eine referenz drauf und die wsdl mit ihren definitionen

da es eine dll ist funktioniert ja das mit dem ändern der references.cs
dann könntest du den rückgabetyp weider auf deinen customtype ummünzen

ansonsten schau dir nochmal den link von oben an, da es ja mit dll funktionieren sollte
ich hab mir das projekt runter geladen und compiliert, danach hatte er autmoatisch die datei schon ins privateassemblies verzeichnis kopiert

dann noch die config einträge (wobei das verlinken auf externe config nicht ging -.-) und er sollte das immer automatisch anpassen (du mußt ja ab und an mal aktualisiern bei änderungen)

falls das nicht klappt und du auch die references.cs nicht ändern möchtest, dann mußt du intern deinen custom type erzeugen lassen und mit den daten aus dem webservice füllen

im endeffekt sehe das dann so aus

webprojekt (arbeitet mit custom type: holt diesen aus dll mit webservice, gibt ihn an control weiter etc.)
-> dll mit custom type
-> controll
-> dll mit webservice

controll (arbeitet nur mit custom type)
-> dll mit custom type

webservice
-> dll mit custom type (spart arbeit auch wenn du die "verknüpfung" wegen webservice verlierst)

dll mit webservice (kapselt alle aufrufe zum webservice und gibt custom type zurück)
-> webservice
-> custom type

sollte funktionieren oder?

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

dadurch das du den webservice an 2 orten wieder eingebunden hast gibt es 2x den typ wieder, die funktionieren aber nicht miteinander

Ganz genau. Ich habe es jetzt so gemacht ,wie von Dir vorgeschlagen. Ich habe noch eine "Zwischenschicht" (also eine eigene Assembly) eingebaut, die den Webservice referenziert und in die Webseite und die Controls-DLL eingebunden wurde.
Damit funktioniert es, wie gewollt.

Ich dachte halt, dass es einen einfachen/schnellen Weg gibt, das ohne zusätzliche Schicht oder "komplizierte Erweiterungen" funktioniert.

Jedenfalls nochmal vielen Dank für Deine Unterstützung!

S
1.047 Beiträge seit 2005
vor 17 Jahren

normaler weise geht das auch fix und unkompliziert.. problem ist halt das du im "projekt" aus 2 verschiedenen komponenten direkt auf den webservice wolltest... was man so gesehen auch als "designfehler" schon fast beschreiben könnte^^

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

was man so gesehen auch als "designfehler" schon fast beschreiben könnte

Findest Du? Ich hab aber keine Ahnung, wie ich das anders lösen könnte?

S
1.047 Beiträge seit 2005
vor 17 Jahren

Original von typhos
Findest Du? Ich hab aber keine Ahnung, wie ich das anders lösen könnte?

hat du doch jetzt geändert 😉

Ich habe noch eine "Zwischenschicht" (also eine eigene Assembly) eingebaut, die den Webservice referenziert und in die Webseite und die Controls-DLL eingebunden wurde.

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Hmm, ja 😁