Procédure : exposer un contrat à des clients SOAP et web
Par défaut, Windows Communication Foundation (WCF) met à disposition les points de terminaison uniquement aux clients SOAP. Dans Procédure : Créer un service web HTTP WCF de base, un point de terminaison est mis à la disposition des clients non SOAP. Dans certains cas, vous pouvez souhaiter rendre le même contrat disponible pour les deux, comme point de terminaison Web et comme point de terminaison SOAP. Cette rubrique explique comment procéder.
Pour définir le contrat de service
Définissez un contrat de service à l’aide d’une interface marquée avec les attributs ServiceContractAttribute, WebInvokeAttribute et WebGetAttribute, comme indiqué dans le code suivant :
[ServiceContract] public interface IService { [OperationContract] [WebGet] string EchoWithGet(string s); [OperationContract] [WebInvoke] string EchoWithPost(string s); }
<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
Notes
Par défaut, WebInvokeAttribute mappe des appels POST à l'opération. Toutefois, vous pouvez spécifier la méthode pour mapper à l'opération un paramètre pour "method=". WebGetAttribute n'a pas de paramètre « method= » et mappe uniquement des appels GET à l'opération de service.
Implémentez le contrat de service, comme indiqué dans le code suivant :
public class Service : IService { public string EchoWithGet(string s) { return "You said " + s; } public string EchoWithPost(string s) { return "You said " + s; } }
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
Pour héberger le service
Créez un objet ServiceHost, comme indiqué dans le code suivant :
ServiceHost host = new ServiceHost(typeof(Service), new Uri("http://localhost:8000"));
Dim host As New ServiceHost(GetType(Service), New Uri("http://localhost:8000"))
Ajoutez un ServiceEndpoint avec BasicHttpBinding pour le point de terminaison SOAP, comme indiqué dans le code suivant :
host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "Soap");
host.AddServiceEndpoint(GetType(IService), New BasicHttpBinding(), "Soap")
Ajoutez un ServiceEndpoint avec WebHttpBinding pour le point de terminaison non SOAP et ajoutez le WebHttpBehavior au point de terminaison, comme indiqué dans le code suivant :
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "Web"); endpoint.Behaviors.Add(new WebHttpBehavior());
Dim endpoint As ServiceEndpoint endpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "Web") endpoint.Behaviors.Add(New WebHttpBehavior())
Appelez
Open()
sur une instance de ServiceHost pour ouvrir l’hôte de service, comme indiqué dans le code suivant :host.Open();
host.Open()
Pour appeler des opérations de service mappées à GET dans un navigateur
- Dans un navigateur web, accédez à «
http://localhost:8000/Web/EchoWithGet?s=Hello, world!
». L’URL contient l’adresse de base du service (http://localhost:8000/
), l’adresse relative du point de terminaison (""), l’opération de service à appeler ("EchoWithGet") et un point d’interrogation suivi d’une liste de paramètres nommés séparés par une esperluette (&).
Pour appeler des opérations de service sur le point de terminaison Web dans le code
Créez une instance de WebChannelFactory<TChannel> au sein d'un bloc
using
, comme illustré dans le code suivant.using (WebChannelFactory<IService> wcf = new WebChannelFactory<IService>(new Uri("http://localhost:8000/Web")))
Using wcf As New WebChannelFactory(Of IService)(New Uri("http://localhost:8000/Web"))
Notes
Close()
est automatiquement appelé sur le canal à la fin du bloc using
.
Créez le canal, puis appelez le service, comme illustré dans le code suivant.
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("http://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);
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("http://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)
Pour appeler des opérations de service sur le point de terminaison SOAP
Créez une instance de ChannelFactory au sein d'un bloc
using
, comme illustré dans le code suivant.using (ChannelFactory<IService> scf = new ChannelFactory<IService>(new BasicHttpBinding(), "http://localhost:8000/Soap"))
Using scf As New ChannelFactory(Of IService)(New BasicHttpBinding(), "http://localhost:8000/Soap")
Créez le canal, puis appelez le service, comme illustré dans le code suivant.
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);
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)
Pour fermer l'hôte de service
Fermez l'hôte de service comme illustré dans le code suivant.
host.Close();
host.Close()
Exemple
Les éléments suivants représentent l’intégralité du code de cette rubrique :
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("http://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("http://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("http://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(), "http://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();
}
}
}
}
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("http://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("http://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("http://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(), "http://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
Compilation du code
Lors de la compilation de Service.cs, référencez System.ServiceModel.dll et System.ServiceModel.Web.dll.