다음을 통해 공유


방법: 기본 WCF 웹 HTTP 서비스 만들기

WCF(Windows Communication Foundation)에서는 웹 엔드포인트를 노출하는 서비스를 만들 수 있습니다. 웹 엔드포인트는 XML 또는 JSON으로 데이터를 보내며 SOAP 봉투가 없습니다. 이 항목에서는 이러한 엔드포인트를 노출하는 방법을 보여 줍니다.

참고 항목

웹 엔드포인트의 보안을 유지하는 유일한 방법은 전송 보안을 사용하여 HTTPS를 통해 웹 엔드포인트를 노출하는 것입니다. 메시지 기반 보안을 사용하는 경우 보안 정보는 일반적으로 SOAP 헤더에 배치되고 비 SOAP 엔드포인트에 보낸 메시지에 SOAP 봉투가 없기 때문에 보안 정보를 배치할 장소가 없으며 전송 보안을 사용해야 합니다.

웹 엔드포인트를 만들려면

  1. ServiceContractAttribute, WebInvokeAttributeWebGetAttribute 특성으로 표시된 인터페이스를 사용하여 서비스 계약을 정의합니다.

    [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 호출을 작업에 매핑합니다. 그러나 "method=" 매개 변수를 지정하여 작업에 매핑할 HTTP 메서드(예: HEAD, PUT 또는 DELETE)를 지정할 수 있습니다. 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. ServiceEndpointWebHttpBehavior와 함께 추가합니다.

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

    참고 항목

    엔드포인트를 추가하지 않으면 WebServiceHost는 자동으로 기본 엔드포인트를 만듭니다. WebServiceHost는 또한 WebHttpBehavior를 추가하고 메타데이터 엔드포인트가 기본 HTTP 엔드포인트와 간섭하지 않도록 HTTP 도움말 페이지 및 WSDL(웹 서비스 기술 언어) GET 기능을 비활성화합니다.

    비 SOAP 엔드포인트를 ""의 URL과 함께 추가하면 엔드포인트에서 작업 호출 시도 시 예기치 못한 동작이 발생합니다. 그 이유는 엔드포인트의 수신 대기 URI가 도움말 페이지(WCF 서비스의 기본 주소를 찾을 때 표시되는 페이지)의 URI와 동일하기 때문입니다.

    이러한 동작이 발생되지 않도록 하기 위해 다음 작업 중 하나를 수행할 수 있습니다.

    • 항상 비 SOAP 엔드포인트에 공백 없는 URI를 지정합니다.
    • 도움말 페이지를 끕니다. 다음 코드를 통해 이 작업을 수행할 수 있습니다.
    ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>();
    sdb.HttpHelpPageEnabled = false;
    
    Dim sdb As ServiceDebugBehavior = host.Description.Behaviors.Find(Of ServiceDebugBehavior)()
    sdb.HttpHelpPageEnabled = False
    
  3. 서비스 호스트를 열고 사용자가 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()
    

    이 샘플에서는 콘솔 애플리케이션에서 웹 스타일 서비스를 호스팅하는 방법을 보여 줍니다. IIS 내에서도 이러한 서비스를 호스팅할 수 있습니다. 이 작업을 수행하려면 다음 코드에서처럼 .svc 파일에서 WebServiceHostFactory 클래스를 지정합니다.

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

브라우저에서 GET에 매핑된 서비스 작업을 호출하려면

  1. 웹 브라우저를 열고 URL "http://localhost:8000/EchoWithGet?s=Hello, world!"을 입력한 다음, Enter 키를 누릅니다. 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을 참조합니다.

참고 항목