Практическое руководство. Как создать простую веб-службу WCF HTTPHow to: Create a Basic WCF Web HTTP Service

Windows Communication Foundation (WCF) позволяет создавать службу, предоставляющую сетевую конечную точку.Windows Communication Foundation (WCF) allows you to create a service that exposes a Web endpoint. Сетевые конечные точки отправляют данные в виде XML-кода или JSON, без конверта SOAP.Web endpoints send data by XML or JSON, there is no SOAP envelope. В этом разделе показано, как предоставить такую конечную точку.This topic demonstrates how to expose such an endpoint.

Примечание

Единственный способ защитить сетевую конечную точку заключается в том, чтобы предоставить ее через протокол HTTPS, используя механизм безопасности транспорта.The only way to secure a Web endpoint is to expose it through HTTPS, using transport security. Поскольку при использовании безопасности на основе сообщений сведения безопасности обычно помещаются в заголовки SOAP и сообщения, отправляемые другим конечным точкам (не SOAP), не содержат конвертов SOAP, негде разместить данные по безопасности и приходится полагаться на механизм безопасности транспорта.When using message-based security, security information is usually placed in SOAP headers and because the messages sent to non-SOAP endpoints contain no SOAP envelope, there is nowhere to place the security information and you must rely on transport security.

Создание сетевой конечной точкиTo create a Web endpoint

  1. Определите контракт службы с использованием интерфейса, отмеченного атрибутами ServiceContractAttribute, WebInvokeAttribute и WebGetAttribute.Define a service contract using an interface marked with the ServiceContractAttribute, WebInvokeAttribute and the WebGetAttribute attributes.

    [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.By default, WebInvokeAttribute maps POST calls to the operation. Однако можно указать метод HTTP (например, HEAD, PUT или DELETE) для сопоставления с операцией, задав параметр «method=».You can, however, specify the HTTP method (for example, HEAD, PUT, or DELETE) to map to the operation by specifying a "method=" parameter. В методе WebGetAttribute отсутствует параметр «method=», при этом метод сопоставляет с операцией службы только вызовы GET.WebGetAttribute does not have a "method=" parameter and only maps GET calls to the service operation.

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

    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
    

Размещение службыTo host the service

  1. Создание объекта WebServiceHost.Create a WebServiceHost object.

    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.Add a ServiceEndpoint with the WebHttpBehavior.

    ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");
    
    Dim ep As ServiceEndpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "")
    

    Примечание

    Если не добавить конечную точку, WebServiceHost автоматически создает конечную точку по умолчанию.If you do not add an endpoint, WebServiceHost automatically creates a default endpoint. WebServiceHost также добавляет WebHttpBehavior и отключает страницу справки HTTP и функцию GET языка описания веб-служб (WSDL), чтобы конечная точка метаданных не мешала конечной точке HTTP по умолчанию.WebServiceHost also adds WebHttpBehavior and disables the HTTP Help page and the Web Services Description Language (WSDL) GET functionality so the metadata endpoint does not interfere with the default HTTP endpoint.

    Добавление конечной точки, не являющейся конечной точкой SOAP, с URL-адресом "" приводит к непредвиденному поведению при попытке вызова операции на конечной точке.Adding a non-SOAP endpoint with a URL of "" causes unexpected behavior when an attempt is made to call an operation on the endpoint. Причиной этого является прослушивания, URI конечной точки совпадает со значением URI страницы справки (страница будет отображаться при просмотре на базовый адрес службы WCF).The reason for this is the listen URI of the endpoint is the same as the URI for the help page (the page that is displayed when you browse to the base address of a WCF service).

    Это можно предотвратить любым из следующих способов.You can do one of the following actions to prevent this from happening:

    • Всегда указывать непустой код URI для конечной точки, не являющейся конечной точкой SOAP.Always specify a non-blank URI for a non-SOAP endpoint.

    • Отключить страницу справки.Turn off the help page. Это можно сделать следующим кодом:This can be done with the following code:

    ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>();
    sdb.HttpHelpPageEnabled = false;
    
    Dim sdb As ServiceDebugBehavior = host.Description.Behaviors.Find(Of ServiceDebugBehavior)()
    sdb.HttpHelpPageEnabled = False
    
  3. Откройте узел службы и подождите, пока пользователь не нажмет клавишу ВВОД.Open the service host and wait until the user presses ENTER.

    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()
    

    В этом образце показано, как разместить веб-службу с помощью консольного приложения.This sample demonstrates how to host a Web-Style service with a console application. Также можно разместить эту службу в IIS.You can also host such a service within IIS. Для этого укажите класс WebServiceHostFactory в файле SVC, как показано в следующем коде.To do this, specify the WebServiceHostFactory class in a .svc file as the following code demonstrates.

    <%ServiceHost
        language=c#
        Debug="true"
        Service="Microsoft.Samples.Service"
        Factory=System.ServiceModel.Activation.WebServiceHostFactory%>
    

Вызов операций службы, сопоставленных с операцией GET, в Internet ExplorerTo call service operations mapped to GET in Internet Explorer

  1. Откройте Internet Explorer и введите "http://localhost:8000/EchoWithGet?s=Hello, world!" и нажмите клавишу ВВОД.Open Internet Explorer and type "http://localhost:8000/EchoWithGet?s=Hello, world!" and press ENTER. URL-адрес содержит базовый адрес службы (http://localhost:8000/), относительный адрес конечной точки ("»), операции службы, чтобы вызов («EchoWithGet») и вопросительный знак и список именованных параметров, разделяемых амперсандом (&).The URL contains the base address of the service (http://localhost:8000/), the relative address of the endpoint (""), the service operation to call ("EchoWithGet"), and a question mark followed by a list of named parameters separated by an ampersand (&).

Вызов операции службы в коде.To call service operations in code

  1. Создайте экземпляр класса ChannelFactory<TChannel> в блоке using.Create an instance of ChannelFactory<TChannel> within a using block.

    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>.Add WebHttpBehavior to the endpoint the ChannelFactory<TChannel> calls.

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

    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.Close the WebServiceHost.

    host.Close();
    
    host.Close()
    

ПримерExample

Ниже приведен полный код этого примера.The following is the full code listing for this example.

// 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
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

Компиляция кодаCompiling the code

При компиляции Service.cs обращается к файлам System.ServiceModel.dll и System.ServiceModel.Web.dll.When compiling Service.cs reference System.ServiceModel.dll and System.ServiceModel.Web.dll.

См. такжеSee also