Cómo exponer un contrato a clientes web y de SOAP
De forma predeterminada, Windows Communication Foundation (WCF) pone los extremos únicamente a disposición de los clientes SOAP. En Cómo: Crear un servicio básico web HTTP de WCF, un extremo se pone a disposición de los clientes que no son SOAP. Puede haber veces en las que desee poner el mismo contrato a disposición de ambos modos, como, por ejemplo, un extremo web y un extremo SOAP. En este tema se muestra un ejemplo sobre cómo hacerlo.
Para definir el contrato de servicio
Defina un contrato de servicio mediante una interfaz marcada con los atributos ServiceContractAttribute, WebInvokeAttribute y WebGetAttribute, tal y como se muestra en el código siguiente.
<ServiceContract()> _ Public Interface IService <OperationContract()> _ <WebGet()> _ Function EchoWithGet(ByVal s As String) As String <OperationContract()> _ <WebInvoke()> _ Function EchoWithPost(ByVal s As String) As String End Interface
[ServiceContract] public interface IService { [OperationContract] [WebGet] string EchoWithGet(string s); [OperationContract] [WebInvoke] string EchoWithPost(string s); }
Nota: De forma predeterminada, WebInvokeAttribute asigna las llamadas POST a la operación. Puede, sin embargo, especificar el método para asignar a la operación especificando un "método =" parámetro. WebGetAttribute no tiene un "método =" parámetro y sólo asigna llamadas GET a la operación de servicio. Implemente el contrato de servicio, tal y como se muestra en el código siguiente.
Public Class Service Implements IService Public Function EchoWithGet(ByVal s As String) As String Implements IService.EchoWithGet Return "You said " + s End Function Public Function EchoWithPost(ByVal s As String) As String Implements IService.EchoWithPost Return "You said " + s End Function End Class
public class Service : IService { public string EchoWithGet(string s) { return "You said " + s; } public string EchoWithPost(string s) { return "You said " + s; } }
Para hospedar el servicio
Cree un objeto ServiceHost, tal y como se muestra en el código siguiente.
Dim host As New ServiceHost(GetType(Service), New Uri("https://localhost:8000"))
ServiceHost host = new ServiceHost(typeof(Service), new Uri("https://localhost:8000"));
Agregue un objeto ServiceEndpoint con BasicHttpBinding para el extremo SOAP, tal y como se muestra en el código siguiente.
host.AddServiceEndpoint(GetType(IService), New BasicHttpBinding(), "Soap")
host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "Soap");
Agregue un objeto ServiceEndpoint con WebHttpBinding para el extremo que no sea SOAP y agregue el WebHttpBehavior al extremo, tal y como se muestra en el código siguiente.
Dim endpoint As ServiceEndpoint endpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "Web") endpoint.Behaviors.Add(New WebHttpBehavior())
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "Web"); endpoint.Behaviors.Add(new WebHttpBehavior());
Llame a
Open()
en una instancia de ServiceHost para abrir el host de servicio, tal y como se muestra en el código siguiente.host.Open()
host.Open();
Para llamar a las operaciones de servicio asignadas a GET en Internet Explorer
- Abra Internet Explorer y escriba "https://localhost:8000/Web/EchoWithGet?s=Hello, world!" y presione ENTRAR. La dirección URL contiene la dirección base del servicio ("https://localhost:8000/"), la dirección relativa del extremo (""), la operación del servicio que se ha de llamar ("EchoWithGet") y un signo de interrogación seguido por una lista de parámetros con nombre separados por una Y comercial (&).
Realización de llamadas a las operaciones de servicio en el extremo web mediante código
Cree una instancia de WebChannelFactory dentro de un bloque
using
, tal y como se muestra en el código siguiente.Using wcf As New WebChannelFactory(Of IService)(New Uri("https://localhost:8000/Web"))
using (WebChannelFactory<IService> wcf = new WebChannelFactory<IService>(new Uri("https://localhost:8000/Web")))
Nota: |
---|
Se llama al método Close() de manera automática en el canal al final del bloque using .
|
Cree un canal y llame al servicio, tal y como se muestra en el código siguiente.
Dim channel As IService = wcf.CreateChannel() Dim s As String Console.WriteLine("Calling EchoWithGet by HTTP GET: ") s = channel.EchoWithGet("Hello, world") Console.WriteLine(" Output: {0}", s) Console.WriteLine("") Console.WriteLine("This can also be accomplished by navigating to") Console.WriteLine("https://localhost:8000/Web/EchoWithGet?s=Hello, world!") Console.WriteLine("in a web browser while this sample is running.") Console.WriteLine("") Console.WriteLine("Calling EchoWithPost by HTTP POST: ") s = channel.EchoWithPost("Hello, world") Console.WriteLine(" Output: {0}", s)
IService channel = wcf.CreateChannel(); string s; Console.WriteLine("Calling EchoWithGet by HTTP GET: "); s = channel.EchoWithGet("Hello, world"); Console.WriteLine(" Output: {0}", s); Console.WriteLine(""); Console.WriteLine("This can also be accomplished by navigating to"); Console.WriteLine("https://localhost:8000/Web/EchoWithGet?s=Hello, world!"); Console.WriteLine("in a web browser while this sample is running."); Console.WriteLine(""); Console.WriteLine("Calling EchoWithPost by HTTP POST: "); s = channel.EchoWithPost("Hello, world"); Console.WriteLine(" Output: {0}", s);
Realización de llamadas a operaciones de servicio en el extremo SOAP
Cree una instancia de ChannelFactory dentro de un bloque
using
, tal y como se muestra en el código siguiente.Using scf As New ChannelFactory(Of IService)(New BasicHttpBinding(), "https://localhost:8000/Soap")
using (ChannelFactory<IService> scf = new ChannelFactory<IService>(new BasicHttpBinding(), "https://localhost:8000/Soap"))
Cree un canal y llame al servicio, tal y como se muestra en el código siguiente.
Dim channel As IService = scf.CreateChannel() Dim s As String Console.WriteLine("Calling EchoWithGet on SOAP endpoint: ") s = channel.EchoWithGet("Hello, world") Console.WriteLine(" Output: {0}", s) Console.WriteLine("") Console.WriteLine("Calling EchoWithPost on SOAP endpoint: ") s = channel.EchoWithPost("Hello, world") Console.WriteLine(" Output: {0}", s)
IService channel = scf.CreateChannel(); string s; Console.WriteLine("Calling EchoWithGet on SOAP endpoint: "); s = channel.EchoWithGet("Hello, world"); Console.WriteLine(" Output: {0}", s); Console.WriteLine(""); Console.WriteLine("Calling EchoWithPost on SOAP endpoint: "); s = channel.EchoWithPost("Hello, world"); Console.WriteLine(" Output: {0}", s);
Cierre del host de servicio.
Cierre el host de servicio, tal y como se muestra en el código siguiente.
host.Close()
host.Close();
Ejemplo
A continuación, se muestra una lista de código completa para este tema.
Imports System
Imports System.Collections.Generic
Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports System.ServiceModel.Web
Imports System.Text
<ServiceContract()> _
Public Interface IService
<OperationContract()> _
<WebGet()> _
Function EchoWithGet(ByVal s As String) As String
<OperationContract()> _
<WebInvoke()> _
Function EchoWithPost(ByVal s As String) As String
End Interface
Public Class Service
Implements IService
Public Function EchoWithGet(ByVal s As String) As String Implements IService.EchoWithGet
Return "You said " + s
End Function
Public Function EchoWithPost(ByVal s As String) As String Implements IService.EchoWithPost
Return "You said " + s
End Function
End Class
Module Program
Sub Main()
Dim host As New ServiceHost(GetType(Service), New Uri("https://localhost:8000"))
host.AddServiceEndpoint(GetType(IService), New BasicHttpBinding(), "Soap")
Dim endpoint As ServiceEndpoint
endpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "Web")
endpoint.Behaviors.Add(New WebHttpBehavior())
Try
host.Open()
Using wcf As New WebChannelFactory(Of IService)(New Uri("https://localhost:8000/Web"))
Dim channel As IService = wcf.CreateChannel()
Dim s As String
Console.WriteLine("Calling EchoWithGet by HTTP GET: ")
s = channel.EchoWithGet("Hello, world")
Console.WriteLine(" Output: {0}", s)
Console.WriteLine("")
Console.WriteLine("This can also be accomplished by navigating to")
Console.WriteLine("https://localhost:8000/Web/EchoWithGet?s=Hello, world!")
Console.WriteLine("in a web browser while this sample is running.")
Console.WriteLine("")
Console.WriteLine("Calling EchoWithPost by HTTP POST: ")
s = channel.EchoWithPost("Hello, world")
Console.WriteLine(" Output: {0}", s)
Console.WriteLine("")
End Using
Using scf As New ChannelFactory(Of IService)(New BasicHttpBinding(), "https://localhost:8000/Soap")
Dim channel As IService = scf.CreateChannel()
Dim s As String
Console.WriteLine("Calling EchoWithGet on SOAP endpoint: ")
s = channel.EchoWithGet("Hello, world")
Console.WriteLine(" Output: {0}", s)
Console.WriteLine("")
Console.WriteLine("Calling EchoWithPost on SOAP endpoint: ")
s = channel.EchoWithPost("Hello, world")
Console.WriteLine(" Output: {0}", s)
Console.WriteLine("")
End Using
Console.WriteLine("Press <Enter> to terminate")
Console.ReadLine()
host.Close()
Catch cex As CommunicationException
Console.WriteLine("An exception occurred: {0}", cex.Message)
host.Abort()
End Try
End Sub
End Module
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;
namespace Microsoft.ServiceModel.Samples.BasicWebProgramming
{
[ServiceContract]
public interface IService
{
[OperationContract]
[WebGet]
string EchoWithGet(string s);
[OperationContract]
[WebInvoke]
string EchoWithPost(string s);
}
public class Service : IService
{
public string EchoWithGet(string s)
{
return "You said " + s;
}
public string EchoWithPost(string s)
{
return "You said " + s;
}
}
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(Service), new Uri("https://localhost:8000"));
host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "Soap");
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "Web");
endpoint.Behaviors.Add(new WebHttpBehavior());
try
{
host.Open();
using (WebChannelFactory<IService> wcf = new WebChannelFactory<IService>(new Uri("https://localhost:8000/Web")))
{
IService channel = wcf.CreateChannel();
string s;
Console.WriteLine("Calling EchoWithGet by HTTP GET: ");
s = channel.EchoWithGet("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
Console.WriteLine("This can also be accomplished by navigating to");
Console.WriteLine("https://localhost:8000/Web/EchoWithGet?s=Hello, world!");
Console.WriteLine("in a web browser while this sample is running.");
Console.WriteLine("");
Console.WriteLine("Calling EchoWithPost by HTTP POST: ");
s = channel.EchoWithPost("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
}
using (ChannelFactory<IService> scf = new ChannelFactory<IService>(new BasicHttpBinding(), "https://localhost:8000/Soap"))
{
IService channel = scf.CreateChannel();
string s;
Console.WriteLine("Calling EchoWithGet on SOAP endpoint: ");
s = channel.EchoWithGet("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
Console.WriteLine("Calling EchoWithPost on SOAP endpoint: ");
s = channel.EchoWithPost("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
}
Console.WriteLine("Press [Enter] to terminate");
Console.ReadLine();
host.Close();
}
catch (CommunicationException cex)
{
Console.WriteLine("An exception occurred: {0}", cex.Message);
host.Abort();
}
}
}
}
Compilar el código
Cuando se compila Service.cs, haga una referencia a System.ServiceModel.dll y System.ServiceModel.Web.dll.
Vea también
Referencia
WebHttpBinding
WebGetAttribute
WebInvokeAttribute
WebServiceHost
ChannelFactory
WebHttpBehavior