HTML Form Handler Sample
来源:互联网 发布:安卓应用市场网站源码 编辑:程序博客网 时间:2024/04/30 22:21
引自:MSDN http://msdn.microsoft.com/en-us/library/bb943485.aspx
Download sample
This sample shows how to extend the Windows Communication Foundation (WCF) Web Programming Model to handle HTML form posts, such as those produced by a Web browser.
Parsing Form Data
HTML form posts are encoded as a series of name-value pairs inside of an HTTP POST entity body with a content type of application/x-www-form-urlencoded. The ParseQueryString method is capable of parsing these values into a NameValueCollection when presented with a raw entity body string. To allow this name/value collection to be passed as a parameter to a WCF service operation, the FormDataProcessor class in the sample uses the IDispatchMessageFormatter extensibility point.
The FormDataProcessor class’s implementation of DeserializeRequest uses ParseQueryString to parse the entity body in a NameValueCollection. A Microsoft Language Integrated Query (LINQ) is used to populate additional method parameters whose values are available through the UriTemplateMatch used to dispatch the request to the operation.
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; };}
Extending WebHttpBehavior with a custom RequestFormatter
You can derive a class from the WebHttpBehavior to extend the WCF runtime for each operation. In the sample, FormProcessingBehavior overrides GetRequestDispatchFormatter to plug in a FormDataFormatter for any Web invoke operation whose last parameter is a NameValueCollection.
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); } }}
Implementing a Form Processing Service
The FormProcessingBehavior hides the details of HTML form processing. The service implementation can then be written without special knowledge of HTML forms, as shown in the following sample code.
[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); } );}
Hosting the Form Processing Service
The service is hosted using the ServiceHost class. The custom FormProcessingBehavior is added to the ServiceEndpoint manually before calling Open as shown in the following sample code.
ServiceHost host = new ServiceHost(typeof(Service), new Uri("http://localhost:8000/FormTest"));ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "");endpoint.Behaviors.Add(new FormProcessingBehavior());
Additionally, the HTTP GET endpoint that exists by default (the endpoint that produces the default HTML help page) is removed by disabling the ServiceMetadataBehavior and ServiceDebugBehavior as shown in the following sample code.
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;}
Running the sample
To view the output of the sample, compile and run the HtmlFormProcessing project and then navigate to http://localhost:8000/FormTest with a Web browser.
See Also
Other Resources
Push-Style Streaming Sample- HTML Form Handler Sample
- C++ signal handler sample
- form/html
- html form
- html的FORM元素
- HTML中的Form属性
- HTML Form issue
- HTML---FORM----RESET
- html:form onsubmit 用法
- html之Form
- html:form的问题
- HTML form Tag
- HTML表单(Form)
- HTML Form Object
- HTML表单(Form)
- form-grid.html
- php & html form 上传
- form input html
- VRVEDP问题
- 回忆 08省赛 吉大(下)
- 回忆 08东北赛
- 改造我们的学习:有钱不会花,抱着金库抓瞎(转自jinxfei)
- IEEE 754 浮点数的表示精度探讨
- HTML Form Handler Sample
- Lab 4: Data Binding with the View-Presenter Pattern
- Djang开发 - 重建app中的表
- 在C#中使用WIA获取扫描仪数据(二、WIA Automation Layer)
- Portal(web应用
- 刮号判断
- Ofbiz 入门教程
- opencms 入门介绍
- Lab 5: Creating a Foundational Module