Как создать простую веб-службу WCF HTTP

Windows Communication Foundation (WCF) позволяет создать службу, которая предоставляет веб-конечную точку. Сетевые конечные точки отправляют данные в виде XML-кода или JSON, без конверта SOAP. В этом разделе показано, как предоставить такую конечную точку.

Примечание.

Единственный способ защитить сетевую конечную точку заключается в том, чтобы предоставить ее через протокол HTTPS, используя механизм безопасности транспорта. Поскольку при использовании безопасности на основе сообщений сведения безопасности обычно помещаются в заголовки SOAP и сообщения, отправляемые другим конечным точкам (не SOAP), не содержат конвертов SOAP, негде разместить данные по безопасности и приходится полагаться на механизм безопасности транспорта.

Создание сетевой конечной точки

  1. Определите контракт службы с использованием интерфейса, отмеченного атрибутами 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.

  2. Реализуйте контракт службы.

    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
    

Размещение службы

  1. Создание объекта 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/"))
    
  2. Добавьте конечную точку 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
    
  3. Откройте узел службы и подождите, пока пользователь не нажмет клавишу ВВОД.

    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 в браузере

  1. Откройте веб-браузер, введите URL-адрес "http://localhost:8000/EchoWithGet?s=Hello, world!", а затем нажмите клавишу ВВОД. URL-адрес содержит базовый адрес службы (), относительный адрес конечной точки (http://localhost:8000/""), операцию службы для вызова ("EchoWithGet") и вопросительный знак, за которым следует список именованных параметров, разделенных амперсандом (&>).

Вызов операции службы в коде.

  1. Создайте экземпляр класса 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")
    
  2. Добавьте WebHttpBehavior в конечную точку, вызываемую объектом ChannelFactory<TChannel>.

    cf.Endpoint.Behaviors.Add(new WebHttpBehavior());
    
    cf.Endpoint.Behaviors.Add(New WebHttpBehavior())
    
  3. Создайте канал и вызовите службу.

    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)
    
  4. Закройте объект 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.

См. также