極簡MVC的實現


我們來打造一個簡單的專用於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();
        }
    }

 

 完成下面這些工作:

  • 根據context請求解析出目標Controller
  • 根據目標Controller以及context請求解析出目標函數Method
  • 在解析Method時,內部還解析了這個Method所涉及到的參數、取值位置(從Request.Form、Request.QueryString, Cookie, Headers等位置,或者Any(Request.Params))、key等

再來看看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...)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM