专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

极简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,怎么样,够容易理解的吧)

72_1.png

配置文件中还要加入相应的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…)

文章永久链接:https://tech.souyunku.com/38938

未经允许不得转载:搜云库技术团队 » 极简MVC的实现

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们