Как создать простую веб-службу WCF HTTP
Windows Communication Foundation (WCF) позволяет создать службу, предоставляющую сетевую конечную точку. Сетевые конечные точки отправляют данные в виде XML-кода или JSON, без конверта SOAP. В этом разделе показано, как предоставить такую конечную точку.
Примечание |
---|
Единственный способ защитить сетевую конечную точку заключается в том, чтобы предоставить ее через протокол HTTPS, используя механизм безопасности транспорта. Поскольку при использовании безопасности на основе сообщений сведения безопасности обычно помещаются в заголовки SOAP и сообщения, отправляемые другим конечным точкам (не SOAP), не содержат конвертов SOAP, негде разместить данные по безопасности и приходится полагаться на механизм безопасности транспорта. |
Создание сетевой конечной точки
Определите контракт службы с использованием интерфейса, отмеченного атрибутами ServiceContractAttribute, WebInvokeAttribute и WebGetAttribute.
<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); }
Примечание По умолчанию атрибут WebInvokeAttribute сопоставляет с операцией вызовы POST. Впрочем, можно указать метод HTTP (например, HEAD, PUT или DELETE) для сопоставления с операцией, задав параметр "method=". У атрибута WebGetAttribute отсутствует параметр "method=", и он сопоставляет с операцией службы только вызовы GET. Реализуйте контракт службы.
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; } }
Размещение службы
Создайте объект WebServiceHost.
Dim host As WebServiceHost = New WebServiceHost(GetType(Service), New Uri("https://localhost:8000/"))
WebServiceHost host = new WebServiceHost(typeof(Service), new Uri("https://localhost:8000/"));
Добавьте конечную точку ServiceEndpoint с поведением WebHttpBehavior.
Dim ep As ServiceEndpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "")
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");
Примечание Если не добавить конечную точку, WebServiceHost автоматически создает конечную точку по умолчанию. WebServiceHost также добавляет поведение WebHttpBehavior и отключает страницу справки HTTP и функцию GET языка WSDL, чтобы конечная точка метаданных не мешала конечной точке HTTP по умолчанию. Добавление конечной точки, не являющейся конечной точкой SOAP, с URL-адресом "" приводит к непредвиденному поведению при попытке вызова операции на конечной точке. Это обусловлено тем, что URI прослушивания конечной точки совпадает с URI страницы справки (отображаемой в браузере, если ввести в его адресную строку базовый адрес службы WCF). Это можно предотвратить любым из следующих способов.
Всегда указывать непустой код URI для конечной точки, не являющейся конечной точкой SOAP.
Отключить страницу справки. Это можно сделать с помощью следующего кода.
Dim sdb As ServiceDebugBehavior = host.Description.Behaviors.Find(Of ServiceDebugBehavior)() sdb.HttpHelpPageEnabled = False
ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>(); sdb.HttpHelpPageEnabled = false;
Откройте узел службы и подождите, пока пользователь не нажмет клавишу ВВОД.
host.Open() Console.WriteLine("Service is running") Console.WriteLine("Press enter to quit...") Console.ReadLine() host.Close()
host.Open(); Console.WriteLine("Service is running"); Console.WriteLine("Press enter to quit..."); Console.ReadLine(); host.Close();
В этом образце показано, как разместить веб-службу с помощью консольного приложения. Также можно разместить эту службу в IIS. Для этого укажите класс WebServiceHostFactory в файле SVC, как показано в следующем коде.
<%ServiceHost language=c# Debug="true" Service="Microsoft.Samples.Service" Factory=System.ServiceModel.Activation.WebServiceHostFactory%>
Вызов операций службы, сопоставленных с операцией GET, в Internet Explorer
- Откройте браузер Internet Explorer, введите "https://localhost:8000/EchoWithGet?s=Hello, world!" и нажмите клавишу ВВОД. Этот URL-адрес содержит базовый адрес службы (https://localhost:8000/), относительный адрес конечной точки (""), вызываемую операцию службы (EchoWithGet), вопросительный знак и следующий за ним список именованных параметров, в качестве разделителя между которыми используется амперсанд (&).
Вызов операции службы в коде.
Создайте экземпляр класса WebChannelFactory в блоке
using
.Using cf As New ChannelFactory(Of IService)(New WebHttpBinding(), "https://localhost:8000")
using (ChannelFactory<IService> cf = new ChannelFactory<IService>(new WebHttpBinding(), "https://localhost:8000"))
Добавьте WebHttpBehavior в конечную точку, вызываемую объектом ChannelFactory.
cf.Endpoint.Behaviors.Add(New WebHttpBehavior())
cf.Endpoint.Behaviors.Add(new WebHttpBehavior());
Создайте канал и вызовите службу.
Dim channel As IService = cf.CreateChannel() Dim s As String Console.WriteLine("Calling EchoWithGet via 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/EchoWithGet?s=Hello, world!") Console.WriteLine("in a web browser while this sample is running.") Console.WriteLine("") Console.WriteLine("Calling EchoWithPost via HTTP POST: ") s = channel.EchoWithPost("Hello, world") Console.WriteLine(" Output: {0}", s)
IService channel = cf.CreateChannel(); string s; Console.WriteLine("Calling EchoWithGet via 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/EchoWithGet?s=Hello, world!"); Console.WriteLine("in a web browser while this sample is running."); Console.WriteLine(""); Console.WriteLine("Calling EchoWithPost via HTTP POST: "); s = channel.EchoWithPost("Hello, world"); Console.WriteLine(" Output: {0}", s);
Закройте объект WebServiceHost.
host.Close()
host.Close();
Пример
Ниже приведен полный код этого примера.
'Service.cs
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 WebServiceHost = New WebServiceHost(GetType(Service), New Uri("https://localhost:8000/"))
Try
Dim ep As ServiceEndpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "")
host.Open()
Using cf As New ChannelFactory(Of IService)(New WebHttpBinding(), "https://localhost:8000")
cf.Endpoint.Behaviors.Add(New WebHttpBehavior())
Dim channel As IService = cf.CreateChannel()
Dim s As String
Console.WriteLine("Calling EchoWithGet via 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/EchoWithGet?s=Hello, world!")
Console.WriteLine("in a web browser while this sample is running.")
Console.WriteLine("")
Console.WriteLine("Calling EchoWithPost via HTTP POST: ")
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
// Service.cs
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)
{
WebServiceHost host = new WebServiceHost(typeof(Service), new Uri("https://localhost:8000/"));
try
{
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");
host.Open();
using (ChannelFactory<IService> cf = new ChannelFactory<IService>(new WebHttpBinding(), "https://localhost:8000"))
{
cf.Endpoint.Behaviors.Add(new WebHttpBehavior());
IService channel = cf.CreateChannel();
string s;
Console.WriteLine("Calling EchoWithGet via 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/EchoWithGet?s=Hello, world!");
Console.WriteLine("in a web browser while this sample is running.");
Console.WriteLine("");
Console.WriteLine("Calling EchoWithPost via HTTP POST: ");
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();
}
}
}
}
Компиляция кода
При компиляции Service.cs обращается к файлам System.ServiceModel.dll и System.ServiceModel.Web.dll.
См. также
Справочник
WebHttpBinding
WebGetAttribute
WebInvokeAttribute
WebServiceHost
WebChannelFactory
WebHttpBehavior