Procedura: esporre un contratto a client SOAP e Web
Per impostazione predefinita, Windows Communication Foundation (WCF) rende disponibili endpoint solo ai client SOAP. In Procedura: creare un servizio HTTP Web WCF viene reso disponibile un endpoint a client non SOAP. Possono verificarsi casi in cui si desidera rendere lo stesso contratto disponibile in entrambi i modi, come endpoint Web e come endpoint SOAP. In questo argomento viene illustrato un esempio di come ottenere tale risultato.
Per definire il contratto di servizio
Definire un contratto di servizio utilizzando un'interfaccia contrassegnata con gli attributi ServiceContractAttribute, WebInvokeAttribute e WebGetAttribute, come mostrato nel codice seguente.
<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: Per impostazione predefinita, WebInvokeAttribute esegue il mapping delle chiamate POST all'operazione. Tuttavia, è possibile definire il metodo di mapping all'operazione specificando un parametro "method=". WebGetAttribute non dispone di un parametro "method=" ed esegue solo il mapping delle chiamate GET all'operazione del servizio. Implementare il contratto di servizio, come mostrato nel codice seguente.
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; } }
Per ospitare il servizio
Creare un oggetto ServiceHost, come mostrato nel codice seguente.
Dim host As New ServiceHost(GetType(Service), New Uri("https://localhost:8000"))
ServiceHost host = new ServiceHost(typeof(Service), new Uri("https://localhost:8000"));
Aggiungere una classe ServiceEndpoint con BasicHttpBinding per l'endpoint SOAP, come mostrato nel codice seguente.
host.AddServiceEndpoint(GetType(IService), New BasicHttpBinding(), "Soap")
host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "Soap");
Aggiungere una classe ServiceEndpoint con WebHttpBinding per l'endpoint non SOAP e aggiungere WebHttpBehavior all'endpoint, come mostrato nel codice seguente.
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());
Chiamare
Open()
su un'istanza di ServiceHostper aprire l'host del servizio, come mostrato nel codice seguente.host.Open()
host.Open();
Per chiamare operazioni del servizio mappate a GET in Internet Explorer
- Aprire Internet Explorer e digitare "https://localhost:8000/Web/EchoWithGet?s=Hello, world!", quindi premere INVIO. L'URL contiene l'indirizzo di base del servizio ("https://localhost:8000/"), l'indirizzo relativo dell'endpoint ("") l'operazione del servizio da chiamare ("EchoWithGet") e un punto interrogativo seguito da un elenco di parametri denominati separati mediante una e commerciale (&).
Per chiamare operazioni del servizio sull'endpoint Web nel codice
Creare un'istanza di WebChannelFactory all'interno di un blocco
using
, come mostrato nel codice seguente.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: |
---|
Close() viene automaticamente chiamato sul canale alla fine del blocco using .
|
Creare il canale e chiamare il servizio, come mostrato nel codice seguente.
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);
Per chiamare operazioni del servizio sull'endpoint SOAP
Creare un'istanza di ChannelFactory all'interno di un blocco
using
, come mostrato nel codice seguente.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"))
Creare il canale e chiamare il servizio, come mostrato nel codice seguente.
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);
Per chiudere l'host del servizio
Chiudere l'host del servizio, come mostrato nel codice seguente.
host.Close()
host.Close();
Esempio
Di seguito è riportato il codice completo per questo argomento.
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();
}
}
}
}
Compilazione del codice
Durante la compilazione di Service.cs fare riferimento a System.ServiceModel.dll e System.ServiceModel.Web.dll.
Vedere anche
Riferimento
WebHttpBinding
WebGetAttribute
WebInvokeAttribute
WebServiceHost
ChannelFactory
WebHttpBehavior