Aufrufen eines REST-Diensts aus einem WCF-DienstCalling a REST-style service from a WCF service

Beim Aufrufen eines REST-Diensts in einem regulären (SOAP-basierten) WCF-Dienst überschreibt der Vorgangskontext in der Dienstmethode (die Informationen über die eingehende Anforderung enthält) den Kontext, der von der ausgehenden Anforderung verwendet werden soll.When calling a REST-style service from a regular (SOAP-based) WCF service, the operation context on the service method (which contains information about the incoming request) overrides the context which should be used by the outgoing request. Dies bewirkt, dass HTTP GET-Anforderungen in HTTP POST-Anforderungen geändert werden.This causes HTTP GET requests to change to HTTP POST requests. Um zu erzwingen, dass der WCF-Dienst den richtigen Kontext zum Aufrufen des REST-Diensts verwendet, erstellen Sie einen neuen OperationContextScope, und rufen Sie den REST-Dienst aus dem Vorgangskontextbereich auf.To force the WCF service to use the right context for calling the REST-style service, create a new OperationContextScope and call the REST-style service from inside the operation context scope. In diesem Thema wird das Erstellen eines einfachen Beispiels beschrieben, das dieses Verfahren veranschaulicht.This topic will describe how to create a simple sample that illustrates this technique.

Definieren des REST-DienstvertragsDefine the REST-style service contract

Definieren Sie einen einfachen REST-Dienstvertrag:Define a simple REST-style service contract:

[ServiceContract]
public interface IRestInterface  
{  
    [OperationContract, WebGet]
    int Add(int x, int y);

    [OperationContract, WebGet]
    string Echo(string input);
}

Implementieren des REST-DienstvertragsImplement the REST-style service contract

Implementieren Sie den REST-Dienstvertrag:Implement the REST-style service contract:

public class RestService : IRestInterface
{
    public int Add(int x, int y)
    {
        return x + y;
    }

    public string Echo(string input)
    {
        return input;
    }
}

Definieren des WCF-DienstvertragsDefine the WCF service contract

Definieren Sie einen WCF-Dienstvertrag, der zum Aufrufen des REST-Diensts verwendet wird:Define a WCF service contract that will be used to call the REST-style service:

[ServiceContract]
public interface INormalInterface
{
    [OperationContract]
    int CallAdd(int x, int y);

    [OperationContract]
    string CallEcho(string input);
}

Implementieren des WCF-DienstvertragsImplement the WCF service contract

Implementieren Sie den WCF-Dienstvertrag:Implement the WCF service contract:

public class NormalService : INormalInterface  
{  
    static MyRestClient client = new MyRestClient(RestServiceBaseAddress);  
    public int CallAdd(int x, int y)  
    {  
        return client.Add(x, y);  
    }  

    public string CallEcho(string input)  
    {  
        return client.Echo(input);  
    }  
}  

Erstellen des Clientproxys für den REST-VertragCreate the client proxy for the REST-style service

Mit System.ServiceModel.ClientBase Clientproxy zu implementieren.Using System.ServiceModel.ClientBase implement the client proxy. Für jede aufgerufene Methode wird ein neuer OperationContextScope erstellt und zum Aufrufen des Vorgangs verwendet.For each method called, a new OperationContextScope is created and used to call the operation.

public class MyRestClient : ClientBase<IRestInterface>, IRestInterface
{
    public MyRestClient(string address)
        : base(new WebHttpBinding(), new EndpointAddress(address))
    {
        this.Endpoint.Behaviors.Add(new WebHttpBehavior());
    }

    public int Add(int x, int y)
    {
        using (new OperationContextScope(this.InnerChannel))
        {
            return base.Channel.Add(x, y);
        }
    }

    public string Echo(string input)
    {
        using (new OperationContextScope(this.InnerChannel))
        {
            return base.Channel.Echo(input);
        }
    }
}

Hosten und Aufrufen der DiensteHost and call the services

Hosten Sie beide Dienste in einer Konsolenanwendung, und fügen Sie die erforderlichen Endpunkte sowie das erforderliche Verhalten hinzu.Host both services in a console app, adding the needed endpoints and behaviors. Rufen Sie dann den regulären WCF-Dienst auf:And then call the regular WCF service:

public static void Main()
{
    ServiceHost restHost = new ServiceHost(typeof(RestService), new Uri(RestServiceBaseAddress));
    restHost.AddServiceEndpoint(typeof(IRestInterface), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
    restHost.Open();

    ServiceHost normalHost = new ServiceHost(typeof(NormalService), new Uri(NormalServiceBaseAddress));
    normalHost.AddServiceEndpoint(typeof(INormalInterface), new BasicHttpBinding(), "");
    normalHost.Open();

    Console.WriteLine("Hosts opened");

    ChannelFactory<INormalInterface> factory = new ChannelFactory<INormalInterface>(new BasicHttpBinding(), new EndpointAddress(NormalServiceBaseAddress));
    INormalInterface proxy = factory.CreateChannel();

    Console.WriteLine(proxy.CallAdd(123, 456));
    Console.WriteLine(proxy.CallEcho("Hello world"));
}

Vollständige CodelisteComplete code listing

Im Folgenden finden Sie eine vollständige Liste des in diesem Thema implementierten Beispiels:The following is a complete listing of the sample implemented in this topic:

public class CallingRESTSample  
{  
    static readonly string RestServiceBaseAddress = "http://" + Environment.MachineName + ":8008/Service";  
    static readonly string NormalServiceBaseAddress = "http://" + Environment.MachineName + ":8000/Service";  

    [ServiceContract]  
    public interface IRestInterface  
    {  
        [OperationContract, WebGet]  
        int Add(int x, int y);  
        [OperationContract, WebGet]  
        string Echo(string input);  
    }  

    [ServiceContract]  
    public interface INormalInterface  
    {  
        [OperationContract]  
        int CallAdd(int x, int y);  
        [OperationContract]  
        string CallEcho(string input);  
    }  

    public class RestService : IRestInterface  
    {  
        public int Add(int x, int y)  
        {  
            return x + y;  
        }  

        public string Echo(string input)  
        {  
            return input;  
        }  
    }  

    public class MyRestClient : ClientBase<IRestInterface>, IRestInterface  
    {  
        public MyRestClient(string address)  
            : base(new WebHttpBinding(), new EndpointAddress(address))  
        {  
            this.Endpoint.Behaviors.Add(new WebHttpBehavior());  
        }  

        public int Add(int x, int y)  
        {  
            using (new OperationContextScope(this.InnerChannel))  
            {  
                return base.Channel.Add(x, y);  
            }  
        }  

        public string Echo(string input)  
        {  
            using (new OperationContextScope(this.InnerChannel))  
            {  
                return base.Channel.Echo(input);  
            }  
        }  
    }  

    public class NormalService : INormalInterface  
    {  
        static MyRestClient client = new MyRestClient(RestServiceBaseAddress);  
        public int CallAdd(int x, int y)  
        {  
            return client.Add(x, y);  
        }  

        public string CallEcho(string input)  
        {  
            return client.Echo(input);  
        }  
    }

    public static void Main()  
    {  
        ServiceHost restHost = new ServiceHost(typeof(RestService), new Uri(RestServiceBaseAddress));  
        restHost.AddServiceEndpoint(typeof(IRestInterface), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());  
        restHost.Open();  

        ServiceHost normalHost = new ServiceHost(typeof(NormalService), new Uri(NormalServiceBaseAddress));  
        normalHost.AddServiceEndpoint(typeof(INormalInterface), new BasicHttpBinding(), "");  
        normalHost.Open();  

        Console.WriteLine("Hosts opened");  

        ChannelFactory<INormalInterface> factory = new ChannelFactory<INormalInterface>(new BasicHttpBinding(), new EndpointAddress(NormalServiceBaseAddress));  
        INormalInterface proxy = factory.CreateChannel();  

        Console.WriteLine(proxy.CallAdd(123, 456));  
        Console.WriteLine(proxy.CallEcho("Hello world"));  
    }  
}

Siehe auchSee Also

Vorgehensweise: Erstellen eines grundlegenden WCF-Web-HTTP-DienstsHow to: Create a Basic WCF Web HTTP Service
Objektmodell für WCF-Web-HTTP-ProgrammierungWCF Web HTTP Programming Object Model