Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Al llamar a un servicio de estilo REST desde un servicio WCF normal (basado en SOAP), el contexto de la operación en el método de servicio (que contiene información sobre la solicitud entrante) invalida el contexto que debe usar la solicitud saliente. Esto hace que las solicitudes HTTP GET cambien a solicitudes HTTP POST. Para forzar que el servicio WCF use el contexto adecuado para llamar al servicio de estilo REST, cree un nuevo OperationContextScope servicio de estilo REST y llame al servicio de estilo REST desde dentro del ámbito del contexto de la operación. En este tema se describe cómo crear un ejemplo sencillo que ilustra esta técnica.
Definición del contrato de servicio de estilo REST
Defina un contrato de servicio de estilo REST simple:
[ServiceContract]
public interface IRestInterface
{
[OperationContract, WebGet]
int Add(int x, int y);
[OperationContract, WebGet]
string Echo(string input);
}
Implementación del contrato de servicio de estilo REST
Implemente el contrato de servicio de estilo REST:
public class RestService : IRestInterface
{
public int Add(int x, int y)
{
return x + y;
}
public string Echo(string input)
{
return input;
}
}
Definición del contrato de servicio WCF
Defina un contrato de servicio WCF que se usará para llamar al servicio de estilo REST:
[ServiceContract]
public interface INormalInterface
{
[OperationContract]
int CallAdd(int x, int y);
[OperationContract]
string CallEcho(string input);
}
Implementación del contrato de servicio WCF
Implemente el contrato de servicio WCF:
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);
}
}
Creación del proxy de cliente para el servicio de estilo REST
Uso ClientBase<TChannel> para implementar el proxy de cliente. Para cada método llamado, se crea un nuevo OperationContextScope y se usa para llamar a la operación.
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);
}
}
}
Hospedar y llamar a los servicios
Hospede ambos servicios en una aplicación de consola, agregando los puntos de conexión y los comportamientos necesarios. A continuación, llame al servicio WCF normal:
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"));
}
Lista de código completa
A continuación se muestra una lista completa del ejemplo implementado en este tema:
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"));
}
}