7 Stimmen

Verwendung von Reflection zum Aufrufen eines ASP.NET-Webdienstes

Angenommen, ich habe einen ASMX-Webdienst, MyService. Der Dienst hat eine Methode, MyMethod. Ich könnte MyMethod auf der Serverseite wie folgt ausführen:

MyService service = new MyService();
service.MyMethod();

Ich muss ähnlich vorgehen, wobei Dienst und Methode erst zur Laufzeit bekannt sind.

Ich gehe davon aus, dass die Reflexion der richtige Weg ist, um das zu erreichen. Leider fällt es mir schwer, dies zu erreichen. Wenn ich diesen Code ausführe:

Type.GetType("MyService", true);

Es wird diese Fehlermeldung ausgegeben:

Der Typ 'MyService' der Assembly 'App_Web__ktsp_r0, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' konnte nicht geladen werden.

Für jeden Hinweis wären wir dankbar.

2voto

Kibbee Punkte 64039

Ich bin mir nicht sicher, ob dies der beste Weg wäre. Der naheliegendste Weg für mich, wäre eine HTTP-Anfrage zu machen, und rufen Sie den Webservice mit einer tatsächlichen HTTP-GET oder POST. Bei Ihrer Methode bin ich mir nicht ganz sicher, wie Sie die Daten, die Sie an den Webdienst senden, einrichten würden. Ich habe etwas Beispielcode in VB.Net hinzugefügt

Dim HTTPRequest As HttpWebRequest
Dim HTTPResponse As HttpWebResponse
Dim ResponseReader As StreamReader
Dim URL AS String
Dim ResponseText As String

URL = "http://www.example.com/MyWebSerivce/MyMethod?arg1=A&arg2=B"

HTTPRequest = HttpWebRequest.Create(URL)
HTTPRequest.Method = "GET"

HTTPResponse = HTTPRequest.GetResponse()

ResponseReader = New StreamReader(HTTPResponse.GetResponseStream())
ResponseText = ResponseReader.ReadToEnd()

2voto

// Versuchen Sie dies ->

    Type t = System.Web.Compilation.BuildManager.GetType("MyServiceClass", true);
    object act = Activator.CreateInstance(t);                
    object o = t.GetMethod("hello").Invoke(act, null);

1voto

Daren Thomas Punkte 64742

Obwohl ich nicht weiß, warum Reflection bei Ihnen nicht funktioniert (ich nehme an, dass der Compiler möglicherweise eine neue Klasse aus Ihrer [WebService] Anmerkungen), finden Sie hier einige Ratschläge, die Ihr Problem lösen könnten:

Halten Sie Ihren WebService einfach, oberflächlich und kurz: Eine Implementierung des Fassadenmusters .

Lassen Sie Ihren Dienst die Berechnung an eine Implementierungsklasse delegieren, die über Reflection leicht aufrufbar sein sollte. Auf diese Weise ist Ihre WebService-Klasse nur eine Fassade für Ihr System - Sie können sogar einen E-Mail-Handler, ein XML-RPC-Frontend usw. hinzufügen, da Ihre Logik nicht an den WebService, sondern an ein tatsächliches Objekt der Geschäftsschicht gekoppelt ist.

Betrachten Sie die WebService-Klassen als Objekte der Benutzeroberflächenschicht in Ihrer Architektur.

1voto

Steve Eisner Punkte 2015

Hier ist eine kurze Antwort, die vielleicht jemand erweitern kann.

Wenn Sie die WSDL-Templating-App (WSDL.exe) verwenden, um Service-Wrapper zu erstellen, wird eine Klasse vom Typ SoapHttpClientProtocol erstellt. Sie können dies auch manuell tun:

public class MyService : SoapHttpClientProtocol
{
    public MyService(string url)
    {
        this.Url = url;
        // plus set credentials, etc.
    }

    [SoapDocumentMethod("{service url}", RequestNamespace="{namespace}", ResponseNamespace="{namespace}", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    public int MyMethod(string arg1)
    {
        object[] results = this.Invoke("MyMethod", new object[] { arg1 });
        return ((int)(results[0]));
    }
}

Ich habe diesen Code nicht getestet, aber ich kann mir vorstellen, dass er eigenständig funktionieren sollte, ohne dass das WSDL-Tool ausgeführt werden muss.

Der Code, den ich zur Verfügung gestellt habe, ist der Aufrufer-Code, der den Webdienst über einen Remote-Aufruf aufruft (auch wenn Sie aus irgendeinem Grund nicht wollen, dass er remote ist). Die Invoke-Methode kümmert sich um die Verpackung als Soap-Aufruf. Der Code von @Dave Ward ist korrekt, wenn Sie den Webdienstaufruf über HTTP umgehen wollen - solange Sie tatsächlich in der Lage sind, die Klasse zu referenzieren. Vielleicht ist der interne Typ nicht "MyService" - Sie müssten den Code des Steuerelements untersuchen, um es genau zu wissen.

0voto

Dave Ward Punkte 58382

@Kibbee: Ich muss den HTTP-Leistungsabfall vermeiden. Es wird kein Fernaufruf sein, so dass all der zusätzliche Overhead sollte unnötig sein.

@Daren: Ich stimme dieser Designphilosophie definitiv zu. Das Problem hier ist, dass ich nicht die Kontrolle über den Dienst oder die ihm zugrunde liegende Geschäftslogik habe.

Dies ist für eine Server-Steuerung die gegen einen beliebigen Dienst/Methode ausgeführt werden müssen, orthogonal zu der Art und Weise, wie der Webdienst selbst implementiert ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X