• 极简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...)

  • 相关阅读:
    js 防止页面后退的方法
    asp.net 设置网页过期
    C#子类调用基类构造备忘
    asp.net 自定义控件 嵌入资源文件 备忘
    CSS实现高度和宽度自适应
    C# 更新SQL Server数据库备注信息从另一数据库
    asp.net mvc4 学习笔记一(基本原理)
    CommittableTransaction和TransactionScope
    Delphi7 错误: Access violation at address ****** in module 'ntdll.dll'. Read of address ******.
    Delphi XE10 IdFtp 错误:No FTP list parsers have been registered
  • 原文地址:https://www.cnblogs.com/aarond/p/A2DMVC.html
Copyright © 2020-2023  润新知