방법: 기본 WCF 웹 HTTP 서비스 만들기
WCF(Windows Communication Foundation)에서는 웹 끝점을 노출하는 서비스를 만들 수 있습니다. 웹 끝점은 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 호출을 작업에 매핑합니다. 그러나 "method=" 매개 변수를 지정하여 작업에 매핑할 HTTP 메서드(예: HEAD, PUT 또는 DELETE)를 지정할 수 있습니다. 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 도움말 페이지 및 WSDL(웹 서비스 기술 언어) GET 기능을 비활성화하여 메타데이터 끝점이 기본 HTTP 끝점을 간섭하지 않도록 합니다. 비 SOAP 끝점을 ""의 URL과 함께 추가하면 끝점에서 작업 호출 시도 시 예기치 못한 동작이 발생합니다. 그 이유는 끝점의 수신 대기 URI가 도움말 페이지(WCF 서비스의 기본 주소를 찾을 때 표시되는 페이지)의 URI와 동일하기 때문입니다. 이러한 동작이 발생되지 않도록 하기 위해 다음 작업 중 하나를 수행할 수 있습니다.
항상 비 SOAP 끝점에 공백 없는 URI를 지정합니다.
도움말 페이지를 끕니다. 다음 코드를 통해 이 작업을 수행할 수 있습니다.
Dim sdb As ServiceDebugBehavior = host.Description.Behaviors.Find(Of ServiceDebugBehavior)() sdb.HttpHelpPageEnabled = False
ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>(); sdb.HttpHelpPageEnabled = false;
서비스 호스트를 열고 사용자가 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%>
Internet Explorer에서 GET에 매핑된 서비스 작업을 호출하려면
- Internet Explorer를 열고 "https://localhost:8000/EchoWithGet?s=Hello, world!"를 입력한 후 Enter 키를 누릅니다. URL에는 서비스 기본 주소("https://localhost:8000/"), 끝점 상대 주소(""), 호출할 서비스 작업("EchoWithGet") 및 앰퍼샌드(&)로 구분된 명명된 매개 변수의 목록 앞에 있는 물음표가 포함됩니다.
코드에서 서비스 작업을 호출하려면
using
블록 내에서 WebChannelFactory 인스턴스를 만듭니다.Using cf As New ChannelFactory(Of IService)(New WebHttpBinding(), "https://localhost:8000")
using (ChannelFactory<IService> cf = new ChannelFactory<IService>(new WebHttpBinding(), "https://localhost:8000"))
ChannelFactory가 호출하는 끝점에 WebHttpBehavior를 추가합니다.
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