Laden...

SOAP/RPC Request auf Webservice von MantisBT?

Erstellt von voodoo44 vor 12 Jahren Letzter Beitrag vor 12 Jahren 3.973 Views
V
voodoo44 Themenstarter:in
82 Beiträge seit 2008
vor 12 Jahren
SOAP/RPC Request auf Webservice von MantisBT?

Hallo liebe User,

ich arbeite gerade daran, meine Bugs (die stehen im MantisBT) mit Hilfe eines C#-Tools zu verwalten.

Es ist kein Problem, irgendwelche Bugs zu entfernen oder neu einzutragen - aber Bugs updaten kann man (zumindest mit dem Tool "MantisConnect") offensichtlich nicht.
Da ich das aber definitiv umsetzen muss/möchte, habe ich mir mal die SOAP-API von Mantis aufgerufen und versucht herauszufinden, wie ich hier Daten updaten kann.

Scheinbar gibt es eine Methode zum Issue-Update auf SOAP-Basis. Leider habe ich überhaupt KEINE Ahnung, wie und was ich nun alles damit anfangen kann.

Wie greife ich auf diese SOAP-API zu?

Es gibt auch eine WSDL-Datei, aber ich hab keine Ahnung, wie genau ich damit irgendwas anfangen kann.

Screenshot zur Update-Methode im Anhang - vielleicht könnt ihr was daraus erkennen.

3.170 Beiträge seit 2006
vor 12 Jahren

Hallo,

normalerweise kann ein Webservice seine zugehörige WSDL über eine bestimmte URL selbst ausliefern. Wenn Du diese URL kennst, kannst Du im VS eine Webservice-Referenz hinzufügen und dort die URL angeben, dabei wird eine Proxyklasse erstellt, mit der Du die API ansteuern kannst.

Kennst Du die URL nicht, hast aber eine WSDL-Datei des Webservice, kannst Du daraus mit dem Tool wsdl.exe eine solche Proxyklasse generieren lassen -> die .cs-Datei, die dabei rauskommt, einfach mit ins Projekt aufnehmen.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

V
voodoo44 Themenstarter:in
82 Beiträge seit 2008
vor 12 Jahren

Hallo,

die WSDL-URL habe ich im Visual Studio (2010) bereits hinzugefügt als Webservice (Verweise->Dienstverweis hinzufügen).

Als Namespacenamen habe ich MantisConnectReference verwendet - unterscheidet sich natürlich vom Namespace meines Projektes, denn der lautet SyncTool.

Auffinden lässt sich dieser Verweis dann auch unter "Service References" als MantisConnectReference.

Wie genau verwende ich diesen Verweis nun? Wie komme ich an die einzelnen Methoden ran?

Über MantisConnectReference.MantisConnectPortTypeClient finde ich zumindest keinen Methodennamen. VS2010 bietet mir hier lediglich equals und ReferenceEquals an.

Was muss ich denn nun tun, um das Ganze ansprechen zu können?
Screenshot vom Objektkatalog im Anhang.

Danke für die Mühe!

3.170 Beiträge seit 2006
vor 12 Jahren

Hallo,

Was muss ich denn nun tun, um das Ganze ansprechen zu können?

Eine Instanz von dem Typen erstellen? Mit new MantisConnectReference.MantisConnectPortTypeClient()?

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

V
voodoo44 Themenstarter:in
82 Beiträge seit 2008
vor 12 Jahren

Tatsache - da ist die Methode ja. Ich dachte, dass ich die auch angezeigt bekomme, wenn ich nur kurz die Klassen "runtertippe" - dass man die vorher instanzieren muss wusste ich nicht. (Und ja: wenn ich sie verwenden will muss ich die Klasse instanziieren, das ist mir klar 😉)

Da ergibt sich aber schon ein neues Problem: Der MantisBT hat anscheinend eine fehlerhafte .NET-Schnittstelle - das heißt ich kann zwar die Methoden verwenden, bekomme ich aber vom Server einen Fehler, kann ich diese nicht auswerten (weil ich ihn nicht kenne) - siehe dazu auch hier:
http://www.mantisbt.org/bugs/view.php?id=12977#bugnotes

Der Bugreporter hat so eine schöne Übersicht angehangen mit welcher er die SOAP-Anfrage gesendet und empfangen hat.

Auf welchem Weg bekomme ich diese zwei XML-Strings? Könnte ich sie mir anzeigen lassen, würde mich das zumindest ein großes Stück weiterbringen - denn dann könnte ich wenigstens von Hand die Fehlermeldungen auslesen und das Programm zum Laufen bekommen - bis der Fehler behoben wurde.

Wie genau komme ich an die Fehlerausschrift, die mir Mantis via SOAP zurückgibt?
Dann könnte ich (wie gesagt) zumindest meine Anwendung fertigstellen.

public void UpdateData()
{
    IssueData newIssue = new IssueData();
    newIssue.description = "UpdateTest";

    try
    {
        MantisConnectPortTypeClient con = new MantisConnectReference.MantisConnectPortTypeClient();
        con.mc_issue_update("administrator", "__myPassword__", "5", newIssue);
    }
    catch(Exception ex)
    {
        System.Console.Write("Error: " + ex);
    }
}
S
324 Beiträge seit 2007
vor 12 Jahren

Guten Morgen,

Mantis benutzt NuSOAP zum Bereitstellend es SOAP Webservices.
Die Leute von NuSoap haben es bis heute nicht geschafft den Fehler raus zu nehmen.

Eigentlich ist es auch kein wirklicher Fehler.
Es ist eine Anforderung von WCF, das die Reihenfolge für die Fault-Message richtig eingehalten wird - WCF ist da etwas pingelig.

Den Fehler bekommst du weg indem du in der nusoap.php in der Fuktion "serialize()" die Zeilen 1066 und 1067 tauscht (faultactor und faultstring).

Die Ganze serialize() muss dann so aussehen:


	function serialize(){
		$ns_string = '';
		foreach($this->namespaces as $k => $v){
			$ns_string .= "\n  xmlns:$k=\"$v\"";
		}
		$return_msg =
			'<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
			'<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
				'<SOAP-ENV:Body>'.
				'<SOAP-ENV:Fault>'.
					$this->serialize_val($this->faultcode, 'faultcode').
					$this->serialize_val($this->faultstring, 'faultstring').
					$this->serialize_val($this->faultactor, 'faultactor').
					$this->serialize_val($this->faultdetail, 'detail').
				'</SOAP-ENV:Fault>'.
				'</SOAP-ENV:Body>'.
			'</SOAP-ENV:Envelope>';
		return $return_msg;
	}


Leider Bekommst du noch andere Fehler danach, weil WCF nicht mir rpc/encoded umgehen kann - WCF will document/literal Style Webservices haben.
Dafür hab ich leider auch noch keine Lösung.

Sehr viel einfacher ist es also einen "alten" .net 2.0 Webservice einzubinden.
Diesen findest du im Dialog zum hinzufügen eines Dienstverweises unten links unter dem Button "Erweitert..." und da dann auch wieder unten.

Damit hast du in jedem Fall keine Probleme mit der Einbindung von PHP Webservices über NuSoap als rpc/encoded Style mit komplexen Datentypen.

Ich hoffe dir damit geholfen zu haben.

V
voodoo44 Themenstarter:in
82 Beiträge seit 2008
vor 12 Jahren

Hallo,

danke der Tipp hat mich definitiv weiter gebracht.
Nun habe ich zumindest mitbekommen, dass der Fehler wo darin liegt, dass ich noch eine Projekt-Id angeben muss. Gesagt getan - und wieder ein neuer Fehler, dem ich nicht so ganz folgen kann.

Fehlermeldung:
System.NullReferenceException wurde nicht behandelt.
Message=Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.

Das Ganze tritt in dieser Zeile auf:

newIssue.project.id = "0";

offensichtlich erwartet newIssue.project.id irgendein Objekt ("string ObjectRef.id" laut VS2010) - was genau passt denn nun dort wieder nicht?

Eine Instanzierung der Klasse

SyncTool.MantisConnectReference.ObjectRef myRef = new MantisConnectReference.ObjectRef();

verweist ja anscheinend irgendwie wieder auf sich selbst und erwartet natürlich auch wieder den gleichen Datentyp wie issue.project.id.

Verschiedene andere Klassen zu instanzieren habe ich auch versucht - immer wieder der gleiche Fehler, ich solle doch ein neues Objekt erzeugen und prüfen, ob irgendwas null wäre.

Kann mir da jemand nochmal helfen? So ganz verstehe ich gerade nicht, was C# da von mir will.

S
324 Beiträge seit 2007
vor 12 Jahren

Was versuchst du da?

NewIssue sieht für mich nach einem neuen Issue aus.
Da er neu ist, wird es ihn wohl noch nicht geben.

Du versuchst newIssue.project.id zu setzen, bist dir aber nicht sicher ob es newIssue.project oder gar newIssue schon als instanziierte klassen gibt?

Da fehlt jetzt wohl etwas c# code um dir folgen zu können 😃

V
voodoo44 Themenstarter:in
82 Beiträge seit 2008
vor 12 Jahren

Quelltext?

Bitteschön:

public void UpdateData()
{
    IssueData newIssue2 = new IssueData();
    newIssue2.description = "UpdateTest";
    newIssue2.project.id = "0";

    try
    {
        MantisConnect myCon = new MantisConnectReference.MantisConnect();
        myCon.mc_issue_update("administrator", "__myPassword__", "5", newIssue2);
    }
    catch(Exception ex)
    {
        System.Console.Write("Error: " + ex);
    }
}

Ich bin aktuell eben am prüfen, wie genau ich die project.id vergeben muss, damit der genannte Fehler nicht mehr auftritt.

V
voodoo44 Themenstarter:in
82 Beiträge seit 2008
vor 12 Jahren

Danke an Sclot, der mir sehr gut via PN weitergeholfen hat!

So ist's richtig:

public void UpdateData()
{
    IssueData newIssue = new IssueData();
    newIssue.description = "Hier haben wir einfach mal irgendwas getestet ..... #blubb";
    newIssue.summary = "Just an UpdateTest";
    newIssue.category = "General";
    newIssue.project = new MantisConnectReference.ObjectRef();
    newIssue.project.id = "1";
    newIssue.project.name = "__myProjectName__";

    try
    {
        MantisConnect myCon = new MantisConnectReference.MantisConnect();
        myCon.mc_issue_update("administrator", "__myPassword__", "5", newIssue);
    }
    catch(Exception ex)
    {
        System.Console.Write("Error: " + ex);
    }
}

Die Zeile

newIssue.project = new MantisConnectReference.ObjectRef();

hat bei mir gefehlt - die war der Knackpunkt!