.NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
前言
刚开始做AJAX应用的时候,经常要手工解析客户端传递的参数,这个过程极其无聊,而且代码中充斥着:Request["xxx"]之类的代码。
这篇文章的目的就是告诉初学者如何自动将客户端用AJAX发送的参数自动绑定为强类型的成员属性或方法参数。
自动绑定到ASPX和ASHX
框架支持
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Happy.Web 8 { 9 public interface IWantAutoBindProperty 10 { 11 } 12 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Happy.Web 8 { 9 [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 10 public sealed class AutoBind : Attribute 11 { 12 } 13 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 using System.Web; 8 9 using Newtonsoft.Json; 10 11 using Happy.ExtensionMethods.Reflection; 12 13 namespace Happy.Web 14 { 15 public class JsonBinderModule : IHttpModule 16 { 17 public void Init(HttpApplication context) 18 { 19 context.PreRequestHandlerExecute += OnPreRequestHandlerExecute; 20 } 21 22 private void OnPreRequestHandlerExecute(object sender, EventArgs e) 23 { 24 if (!(HttpContext.Current.CurrentHandler is IWantAutoBindProperty)) 25 { 26 return; 27 } 28 29 var properties = HttpContext.Current.CurrentHandler.GetType().GetProperties(); 30 31 foreach (var property in properties) 32 { 33 if (!property.IsDefined(typeof(AutoBind), true)) 34 { 35 continue; 36 } 37 38 string json = HttpContext.Current.Request[property.Name]; 39 40 var value = JsonConvert.DeserializeObject(json, property.PropertyType); 41 42 property.SetValue(HttpContext.Current.Handler, value); 43 } 44 } 45 46 public void Dispose() 47 { 48 } 49 } 50 }
代码示例
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <configuration> 4 5 <system.web> 6 <compilation debug="false" targetFramework="4.0" /> 7 <httpModules> 8 <add name="JsonBinderModule" type="Happy.Web.JsonBinderModule"/> 9 </httpModules> 10 </system.web> 11 12 </configuration>
1 /// <reference path="../ext-all-debug-w-comments.js" /> 2 var data = { 3 Name: '段光伟', 4 Age: 28 5 }; 6 7 Ext.Ajax.request({ 8 url: '../handlers/JsonBinderTest.ashx', 9 method: 'POST', 10 params: { user: Ext.encode(data) } 11 });
1 <%@ WebHandler Language="C#" Class="JsonBinderTest" %> 2 3 using System; 4 using System.Web; 5 6 using Happy.Web; 7 8 public class JsonBinderTest : IHttpHandler, IWantAutoBindProperty 9 { 10 [AutoBind] 11 public User user { get; set; } 12 13 public void ProcessRequest(HttpContext context) 14 { 15 context.Response.ContentType = "text/plain"; 16 context.Response.Write(string.Format("姓名:{0},年龄:{1}", user.Name, user.Age)); 17 } 18 19 public bool IsReusable 20 { 21 get 22 { 23 return false; 24 } 25 } 26 } 27 28 public class User 29 { 30 public string Name { get; set; } 31 32 public int Age { get; set; } 33 }
运行结果
自动绑定到MVC
框架支持
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 using System.Web.Mvc; 8 9 using Newtonsoft.Json; 10 11 namespace Tenoner.Web.Mvc 12 { 13 public class JsonBinder : IModelBinder 14 { 15 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 16 { 17 string json = controllerContext.HttpContext.Request[bindingContext.ModelName]; 18 19 return JsonConvert.DeserializeObject(json, bindingContext.ModelType); 20 } 21 } 22 }
代码示例
此处省略代码示例,有兴趣的朋友请留言交流。
备注
有些朋友应该能想到,这种模式不止能用在AJAX场景,其它场景也可以使用。