我們來打造一個簡單的專用于json調用的mvc實現,最終會將如下的C#代碼暴露給js調用(代碼在最后面有下載):
public class UserController { public static Json GetUser( [HttpQueryString("x_user")] int userId, [HttpQueryString("msg")] string msg) { Json json = new Json(); json.IsSuccess = true; json.Data = new { Field1=userId, Field2=msg }; return json; } }
上面這些用到的class,如:Json, HttpQueryString之類的都是自己寫的,不是asp.net mvc的類。
(HttpQueryString("x_user")代表修飾的變量userId的值是從QueryString集合中獲取的,并且key為x_user,怎么樣,夠容易理解的吧)
配置文件中還要加入相應的HandlerFactory(代表符合Ajax/*.ashx的路徑都會被MvcHandlerFactory處理,目前只實現了JsonHttpHandler):
<httpHandlers> <add type="Mvc.Factories.MvcHandlerFactory, Mvc" path="ajax/*.ashx" verb="*"/></httpHandlers>
入口找到了,就好辦了,我們來看看這個MvcHandlerFactory:
public class MvcHandlerFactory:IHttpHandlerFactory { public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated) { ControllerDescriptor controllerDescriptor = ControllerFactory.Resolve(context); //解析當前請求的ControllerDescriptor if (controllerDescriptor == null) throw new Exception("沒有找到相應的Controller"); MethodDescriptor methodDescriptor = MethodFactory.Resolve(controllerDescriptor, context);//解析當前請求的MethodDescriptor if (methodDescriptor == null) throw new Exception("沒有找到相應的調用方法"); IHttpHandler handler = new JsonHttpHandler(controllerDescriptor, methodDescriptor);//由于目前只做了Json處理器,因此直接硬編碼此類 return handler; } public void ReleaseHandler(IHttpHandler handler) { throw new NotImplementedException(); } }
完成下面這些工作:
再來看看JsonHttpHandler:
public class JsonHttpHandler:IHttpHandler { PRivate ControllerDescriptor controllerDescriptor; private MethodDescriptor methodDescriptor; private javaScriptSerializer jsonSerializer = new JavascriptSerializer();//用了ms的json序列化器 public JsonHttpHandler(ControllerDescriptor controllerDescriptor, MethodDescriptor methodDescriptor) { this.controllerDescriptor = controllerDescriptor; this.methodDescriptor = methodDescriptor; } public bool IsReusable//無所謂里面的返回值,ms用不到這個value,都是false { get { throw new NotImplementedException(); } } public void ProcessRequest(HttpContext context) { MethodInfo mi = this.controllerDescriptor.ControllerType.GetMethod(this.methodDescriptor.MethodName); List<object> parameters = new List<object>(); foreach (var pd in this.methodDescriptor.ParameterDescriptors) { object value = ParameterParser.GetValue(context, pd);//遍歷all參數,并且從相應的location取值 parameters.Add(value); } object result=mi.Invoke(null, parameters.ToArray());//調用具體Controller中的函數,由于是靜態函數,因此傳入了null作為instance string json=jsonSerializer.Serialize(result);//序列化為json字符串 context.Response.Write(json); } }
還需要在global中增加搜索所有Controller后綴的class到注冊Dictionary中,這里就是些遍歷,大家可以看代碼,代碼就不貼了
目前這個框架是簡陋的,不過也看到了有很多能插入的點,比如[RequestLimit(HttpRequestType.Post)]等,大家懂的。
一旦自己能深入到框架內部,許多難題就不再是難題了,可以很快解決。
附上vs2012寫的代碼(家里電腦只有vs2012,沒有vs2010...)
新聞熱點
疑難解答