Как создать простую веб-службу WCF HTTP
Windows Communication Foundation (WCF) позволяет создать службу, которая предоставляет веб-конечную точку. Сетевые конечные точки отправляют данные в виде XML-кода или JSON, без конверта SOAP. В этом разделе показано, как предоставить такую конечную точку.
Примечание.
Единственный способ защитить сетевую конечную точку заключается в том, чтобы предоставить ее через протокол HTTPS, используя механизм безопасности транспорта. Поскольку при использовании безопасности на основе сообщений сведения безопасности обычно помещаются в заголовки SOAP и сообщения, отправляемые другим конечным точкам (не SOAP), не содержат конвертов SOAP, негде разместить данные по безопасности и приходится полагаться на механизм безопасности транспорта.
Создание сетевой конечной точки
Определите контракт службы с использованием интерфейса, отмеченного атрибутами ServiceContractAttribute, WebInvokeAttribute и WebGetAttribute.
[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
Примечание.
По умолчанию атрибут WebInvokeAttribute сопоставляет с операцией вызовы POST. Однако можно указать метод HTTP (например, HEAD, PUT или DELETE) для сопоставления с операцией, задав параметр «method=». В методе WebGetAttribute отсутствует параметр «method=», при этом метод сопоставляет с операцией службы только вызовы GET.
Реализуйте контракт службы.
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
Размещение службы
Создание объекта WebServiceHost.
WebServiceHost host = new WebServiceHost(typeof(Service), new Uri("http://localhost:8000/"));
Dim host As WebServiceHost = New WebServiceHost(GetType(Service), New Uri("http://localhost:8000/"))
Добавьте конечную точку ServiceEndpoint с поведением WebHttpBehavior.
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");
Dim ep As ServiceEndpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "")
Примечание.
Если не добавить конечную точку, WebServiceHost автоматически создает конечную точку по умолчанию. WebServiceHost также добавляет WebHttpBehavior и отключает страницу справки HTTP и функцию GET языка описания веб-служб (WSDL), чтобы конечная точка метаданных не мешала конечной точке HTTP по умолчанию.
Добавление конечной точки, не являющейся конечной точкой SOAP, с URL-адресом "" приводит к непредвиденному поведению при попытке вызова операции на конечной точке. Причина этого заключается в том, что URI прослушивания конечной точки совпадает с универсальным кодом ресурса (URI) для страницы справки (страница, отображаемая при переходе к базовому адресу службы WCF).
Это можно предотвратить любым из следующих способов.
- Всегда указывать непустой код URI для конечной точки, не являющейся конечной точкой SOAP.
- Отключить страницу справки. Это можно сделать с помощью следующего кода:
ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>(); sdb.HttpHelpPageEnabled = false;
Dim sdb As ServiceDebugBehavior = host.Description.Behaviors.Find(Of 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 в браузере
- Откройте веб-браузер, введите URL-адрес "
http://localhost:8000/EchoWithGet?s=Hello, world!
", а затем нажмите клавишу ВВОД. URL-адрес содержит базовый адрес службы (), относительный адрес конечной точки (http://localhost:8000/
""), операцию службы для вызова ("EchoWithGet") и вопросительный знак, за которым следует список именованных параметров, разделенных амперсандом (&>).
Вызов операции службы в коде.
Создайте экземпляр класса ChannelFactory<TChannel> в блоке
using
.using (ChannelFactory<IService> cf = new ChannelFactory<IService>(new WebHttpBinding(), "http://localhost:8000"))
Using cf As New ChannelFactory(Of IService)(New WebHttpBinding(), "http://localhost:8000")
Добавьте WebHttpBehavior в конечную точку, вызываемую объектом ChannelFactory<TChannel>.
cf.Endpoint.Behaviors.Add(new WebHttpBehavior());
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("http://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);
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("http://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
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("http://localhost:8000/"));
try
{
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");
host.Open();
using (ChannelFactory<IService> cf = new ChannelFactory<IService>(new WebHttpBinding(), "http://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("http://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
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("http://localhost:8000/"))
Try
Dim ep As ServiceEndpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "")
host.Open()
Using cf As New ChannelFactory(Of IService)(New WebHttpBinding(), "http://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("http://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 обращается к файлам System.ServiceModel.dll и System.ServiceModel.Web.dll.