HTML Form Handler 샘플
이 샘플에서는 WCF(Windows Communication Foundation) 웹 프로그래밍 모델을 확장하여 웹 브라우저에서 생성한 폼 게시와 같은 HTML 폼 게시를 처리하는 방법을 보여 줍니다.
참고
이 샘플을 빌드하고 실행하려면 .NET Framework 버전 3.5가 설치되어 있어야 하며 프로젝트 및 솔루션 파일을 열려면 Visual Studio 2008이 필요합니다.
폼 데이터 구문 분석
HTML 폼 게시는 콘텐츠 형식이 application/x-www-form-urlencoded인 HTTP POST 엔터티 본문 내에서 일련의 이름-값 쌍으로 인코딩됩니다. ParseQueryString 메서드는 원시 엔터티 본문 문자열로 제공될 때 이러한 값을 NameValueCollection으로 구문 분석할 수 있습니다. 이 이름/값 컬렉션을 매개 변수로 WCF 서비스 작업에 전달하기 위해 샘플의 FormDataProcessor
클래스에서는 IDispatchMessageFormatter 확장 지점을 사용합니다.
DeserializeRequest의 FormDataProcessor
클래스 구현에서는 ParseQueryString을 사용하여 NameValueCollection의 엔터티 본문을 구문 분석합니다. LINQ(Microsoft Language Integrated Query)는 작업에 대한 요청을 디스패치하는 데 사용된 UriTemplateMatch를 통해 값을 사용할 수 있는 추가 메서드 매개 변수를 채우는 데 사용됩니다.
public void DeserializeRequest(System.ServiceModel.Channels.Message message, object[] parameters)
{
if (WebOperationContext.Current.IncomingRequest.ContentType
!= "application/x-www-form-urlencoded")
throw new InvalidDataException("Unexpected content type");
Stream s = StreamMessageHelper.GetStream(message);
string formData = new StreamReader(s).ReadToEnd();
NameValueCollection parsedForm =
System.Web.HttpUtility.ParseQueryString(formData);
UriTemplateMatch match =
message.Properties["UriTemplateMatchResults"] as UriTemplateMatch;
ParameterInfo[] paramInfos = operation.SyncMethod.GetParameters();
var binder = CreateParameterBinder( match );
object[] values = (from p in paramInfos
select binder(p)).ToArray<Object>();
values[paramInfos.Length - 1] = parsedForm;
values.CopyTo(parameters, 0);
}
private Func<ParameterInfo, object> CreateParameterBinder(UriTemplateMatch match)
{
QueryStringConverter converter = new QueryStringConverter();
return delegate( ParameterInfo pi )
{
string value = match.BoundVariables[pi.Name];
if (converter.CanConvert(pi.ParameterType) && value != null)
return converter.ConvertStringToValue(value,
pi.ParameterType);
else
return value;
};
}
사용자 지정 RequestFormatter로 WebHttpBehavior 확장
WebHttpBehavior에서 클래스를 파생시켜 각 작업의 WCF 런타임을 확장할 수 있습니다. 이 샘플에서 FormProcessingBehavior
는 GetRequestDispatchFormatter를 재정의하여 마지막 매개 변수가 NameValueCollection인 모든 웹 호출 작업에 대해 FormDataFormatter
를 연결합니다.
public class FormProcessingBehavior : WebHttpBehavior
{
protected override IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
{
//Messages[0] is the request message
MessagePartDescriptionCollection parts =
operationDescription.Messages[0].Body.Parts;
//This formatter looks for [WebInvoke] operations that have
// their last parameter typed as NameValueCollection
if (operationDescription.Behaviors.Find<WebInvokeAttribute>()
!= null &&
parts.Count > 0 &&
parts[parts.Count - 1].Type == typeof(NameValueCollection))
{
return new FormDataRequestFormatter(operationDescription);
}
else
{
return base.GetRequestDispatchFormatter(
operationDescription, endpoint);
}
}
}
폼 처리 서비스 구현
FormProcessingBehavior
는 HTML 폼 처리에 대한 세부 정보를 숨깁니다. 그러면 다음 샘플 코드와 같이 HTML 폼에 대한 전문 지식이 없어도 서비스 구현을 작성할 수 있습니다.
[OperationContract]
[WebInvoke(UriTemplate = "ProcessForm/{templateParam1}/{templateParam2}")]
public Message ProcessForm(string templateParam1, string templateParam2, NameValueCollection formData)
{
DumpValues(Console.Out, templateParam1, templateParam2, formData);
return StreamMessageHelper.CreateMessage(
MessageVersion.None, "",
"text/plain",
delegate(Stream output)
{
TextWriter writer = new StreamWriter(output);
DumpValues(writer, templateParam1, templateParam2, formData);
}
);
}
참고
StreamMessageHelper
클래스에 대한 자세한 내용은 Push-Style Streaming 샘플을 참조하십시오.
폼 처리 서비스 호스팅
이 서비스는 ServiceHost 클래스를 사용하여 호스팅됩니다. 다음 샘플 코드와 같이 Open을 호출하기 전에 사용자 지정 FormProcessingBehavior
를 ServiceEndpoint에 수동으로 추가합니다.
ServiceHost host = new ServiceHost(typeof(Service), new Uri("https://localhost:8000/FormTest"));
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "");
endpoint.Behaviors.Add(new FormProcessingBehavior());
또한 다음 샘플 코드와 같이 ServiceMetadataBehavior 및 ServiceDebugBehavior를 비활성화하여 기본적으로 존재하는 HTTP GET 끝점(기본 HTML 도움말 페이지를 생성하는 끝점)을 제거합니다.
ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb != null)
{
smb.HttpGetEnabled = false;
smb.HttpsGetEnabled = false;
}
ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>();
if (sdb != null)
{
sdb.HttpHelpPageEnabled = false;
}
샘플 실행
샘플 출력을 보려면 HtmlFormProcessing
프로젝트를 컴파일하고 실행한 다음 웹 브라우저를 사용하여 https://localhost:8000/FormTest로 이동합니다.
참고 항목
작업
Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.