Vorgehensweise: Verfügbarmachen eines Vertrags für SOAP- und Webclients
Standardmäßig stellt Windows Communication Foundation (WCF) Endpunkte nur für SOAP-Clients zur Verfügung. In Vorgehensweise: Erstellen eines grundlegenden WCF-Web-HTTP-Diensts wird ein Endpunkt für Nicht-SOAP-Clients zur Verfügung gestellt. Manchmal möchten Sie jedoch einen Vertrag für beide Wege verfügbar machen, als Webendpunkt und als SOAP-Endpunkt. In diesem Thema wird ein Beispiel für diesen Vorgang gezeigt.
So definieren Sie den Dienstvertrag
Definieren Sie einen Dienstvertrag mit einer Schnittstelle, die mit den Attributen ServiceContractAttribute, WebInvokeAttribute und WebGetAttribute gekennzeichnet ist, wie im folgenden Code gezeigt:
[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
Hinweis
Standardmäßig ordnet WebInvokeAttribute dem Vorgang POST-Aufrufe zu. Sie können jedoch die Methode, die dem Vorgang zugeordnet werden soll, mit einem "method="-Parameter angeben. WebGetAttribute besitzt keinen "method="-Parameter und ordnet dem Dienstvorgang nur GET-Aufrufe zu.
Implementieren Sie den Dienstvertrag, wie im folgenden Code gezeigt:
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
So hosten Sie den Dienst
Erstellen Sie ein ServiceHost-Element, wie im folgenden Code gezeigt:
ServiceHost host = new ServiceHost(typeof(Service), new Uri("http://localhost:8000"));
Dim host As New ServiceHost(GetType(Service), New Uri("http://localhost:8000"))
Fügen Sie einen ServiceEndpoint mit BasicHttpBinding für den SOAP-Endpunkt hinzu, wie im folgenden Code gezeigt:
host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "Soap");
host.AddServiceEndpoint(GetType(IService), New BasicHttpBinding(), "Soap")
Fügen Sie einen ServiceEndpoint mit WebHttpBinding für einen Nicht-SOAP-Endpunkt hinzu und fügen Sie das WebHttpBehavior dem Endpunkt hinzu, wie im folgenden Code gezeigt:
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())
Rufen Sie
Open()
für eine ServiceHost-Instanz hinzu, um den Diensthost zu öffnen, wie im folgenden Code gezeigt:host.Open();
host.Open()
So rufen Sie Dienstvorgänge auf, die GET in einem Browser zugeordnet sind
- Navigieren Sie in einem Webbrowser zu „
http://localhost:8000/Web/EchoWithGet?s=Hello, world!
“. Die URL enthält die Basisadresse des Diensts (http://localhost:8000/
), die relative Adresse des Endpunkts (""), den aufzurufenden Dienstvorgang („EchoWithGet“) und ein Fragezeichen, gefolgt von einer Liste der benannten Parameter, die durch ein kaufmännisches Und-Zeichen (&) getrennt sind.
So rufen Sie Dienstvorgänge auf dem Webendpunkt im Code auf
Erstellen Sie eine Instanz von WebChannelFactory<TChannel> in einem
using
-Block, wie im folgenden Code veranschaulicht.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"))
Hinweis
Close()
wird am Ende des using
-Blocks automatisch für den Kanal aufgerufen.
Erstellen Sie den Kanal, und rufen Sie den Dienst auf, wie im folgenden Code gezeigt.
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)
So rufen Sie Dienstvorgänge an dem SOAP-Endpunkt auf
Erstellen Sie eine Instanz von ChannelFactory in einem
using
-Block, wie im folgenden Code veranschaulicht.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")
Erstellen Sie den Kanal, und rufen Sie den Dienst auf, wie im folgenden Code gezeigt.
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)
So schließen Sie den Diensthost
Schließen Sie den Diensthost, wie im folgenden Code gezeigt.
host.Close();
host.Close()
Beispiel
Unten folgt die vollständige Codeauflistung für dieses Thema:
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
Kompilieren des Codes
Verweisen Sie beim Kompilieren der Datei Service.cs auf System.ServiceModel.dll und System.ServiceModel.Web.dll.