• 实现的功能

    • 简单的路由系统
    • 支持中间件
    • 简单Filter支持
    • 只支持HttpPost、HttpGet
    • 使用Dotliquid做为视图渲染引擎
  • 核心实现

    • HttpChannel

      • 复制监听Tcp请求,并按照Http协议将tcp数据传输解析为HttpRequest数据实例,解析完调用HttpHandler继续下一步处理
    • HttpRequest

      • 单次Http请求信息,包含 HttpMethod、Version、Url、HttpHeader、Cookies等信息
    • HttpResponse

      • Http响应信息
    • DefaultHttpHandler

      • 实现IHttpHandler,负责Middleware责任链的创建、执行

      •   private IMiddleware BuildMiddlewareChain()
        {
        var builder = new MiddlewareChainBuilder();
        builder.Use(new StaticFileMiddleware());
        builder.Use(new MvcMiddleware(route));
        return builder.Build();
        } public async Task<HttpResponse> ProcessAsync(HttpRequest httpRequest)
        {
        var chain = BuildMiddlewareChain();
        return await chain.Invoke(httpRequest);
        }
    • MvcMiddleware

      • 内置的中间件,mvc功能具体实现[FIlter模式实现]

      • public override async Task<HttpResponse> Invoke(HttpRequest httpRequest)
        {
        try
        {
        var context = new ActionExecuteContext
        {
        HttpRequest = httpRequest
        }; var (controller, methodInfo, parameter) = route.Route(httpRequest);
        if (controller == null)
        {
        return await HttpResponseHelper.CreateNotFoundResponseAsync();
        } context.Controller = controller;
        context.Action = methodInfo;
        ((ControllerBase)controller).Request = httpRequest; var filterList = GetFilters(controller, methodInfo);
        var stack = new Stack<IFilter>();
        for (var i = 0; i < filterList.Count; i++)
        {
        var filter = filterList[i];
        await filter.OnActionExecutingAsync(context);
        if (context.Final)
        {
        return context.HttpResponse;
        }
        stack.Push(filter);
        } await controller.OnActionExecutingAsync(context); if (context.Final)
        {
        return context.HttpResponse;
        } var parameters = new List<object>();
        if (parameter != null)
        {
        parameters.Add(parameter);
        } if (methodInfo.ReturnType.IsGenericType) //Task<IActionResult>
        {
        var actionResult = await (methodInfo.Invoke(controller, parameters.ToArray()) as Task<IActionResult>);
        context.HttpResponse = await actionResult.ExecuteResultAsync();
        }
        else
        {
        var actionResult = methodInfo.Invoke(controller, parameters.ToArray()) as IActionResult;
        context.HttpResponse = await actionResult.ExecuteResultAsync();
        } context.HttpResponse.Cookies.AddRange(controller.ResponseCookie); await controller.OnActionExecutedAsync(context); if (context.Final)
        {
        return context.HttpResponse;
        } while (stack.Count != 0)
        {
        var filter = stack.Pop();
        await filter.OnActionExecutedAsync(context); if (context.Final)
        {
        return context.HttpResponse;
        }
        }
        return context.HttpResponse;
        }
        catch (Exception e)
        {
        return await HttpResponseHelper.CreateDefaultErrorResponseAsync(e);
        }
        }
    • EasyRoute

      • 实现最简单的路由解析【URL---> IController/Method】

      • Controller实例化使用netcore自带的IOC框架实现

      • public (IController, MethodInfo, object) Route(HttpRequest request)
        {
        var path = request.AbsolutePath;
        Type controllerType;
        MethodInfo methodInfo;
        switch (request.HttpMethod)
        {
        case HttpMethod.Get:
        if (httpGetRoutes.ContainsKey(path))
        {
        (controllerType, methodInfo) = httpGetRoutes[path];
        }
        else
        {
        return (null, null, null);
        }
        break;
        case HttpMethod.Post:
        if (httpPostRoutes.ContainsKey(path))
        {
        (controllerType, methodInfo) = httpPostRoutes[path];
        }
        else
        {
        return (null, null, null);
        }
        break;
        default://Unsupport httpmethod
        return (null, null, null);
        }
        var controllerObj = ServiceLocator.Instance.GetService(controllerType) as IController;
        //var controllerObj = Activator.CreateInstance(controllerType) as IController;
        object parameter = null;
        var parameterType = methodInfo.GetParameters().SingleOrDefault()?.ParameterType;
        if (parameterType != null)
        {
        parameter = ResolveParameter(parameterType, request);
        } return (controllerObj, methodInfo, parameter);
        }
    • IActionResult

      • 执行结果的抽象,类比MVC的IActionResult

      • 内置类型

        • HttpStatusCodeResult:只返回特定StatusCode,没有具体内容

        • JsonResult:返回JSON结果,content-type:application/json

        • RedirectResult:返回302

        • ViewResult:使用DotLiquid作为视图渲染引擎

          public async Task<HttpResponse> ExecuteResultAsync()
          {
          var absoluteName = $"Views/{ViewName}";
          Template template;
          if (viewCache.ContainsKey(absoluteName))
          {
          template = viewCache[absoluteName];
          }
          else
          {
          var templateStr = Template.FileSystem.ReadTemplateFile(new Context(CultureInfo.CurrentCulture), absoluteName);
          template = Template.Parse(templateStr);
          viewCache.Add(absoluteName, template);
          }
          var content = template.Render(Hash.FromAnonymousObject(ViewData)); var res = new HttpResponse(); await res.WriteBodyAsync(Constants.DefaultEncoding.GetBytes(content)); return res;
          }
    • IController

      • mvc控制器接口
    • HttpCookie

      • cookie操作类
    • IFilter

      • 过滤器接口

         public interface IFilter
        {
        int Order { get; set; }
        Task OnActionExecutingAsync(ActionExecuteContext context);
        Task OnActionExecutedAsync(ActionExecuteContext context);
        }
  • 其他

    • 本项目只为学习使用,如有错误,请指出
    • 本项目为另一个项目 EasyProxy 的附属产物,所以没有独立的github仓库,具体目录为 HttpServer

netcore mvc 的简单实现的更多相关文章

  1. .NetCore MVC中的路由(2)在路由中使用约束

    p { margin-bottom: 0.25cm; direction: ltr; color: #000000; line-height: 120%; orphans: 2; widows: 2 ...

  2. .NetCore MVC中的路由(1)路由配置基础

    .NetCore MVC中的路由(1)路由配置基础 0x00 路由在MVC中起到的作用 前段时间一直忙于别的事情,终于搞定了继续学习.NetCore.这次学习的主题是MVC中的路由.路由是所有MVC框 ...

  3. .netcore mvc docker环境jenkins一键部署(DevOps)

    [前言] DevOps方面的文章很早之前就想分享了,挤出一点时间把前段时间搭建的一些提高开发效率的东西给大家分享一下吧. 本文介绍了一个.netcore mvc web项目,从项目push到githu ...

  4. windows 下开发的 .netCore MVC 部署到 Linux(Mint)

    这两天在公司跟同事偶然聊到 .netCore,说到一些趋势什么的.但是说来说去自己也没试过在Linux 机子上部署过,所以就试一下. 尝试之前也在网上看了一些文章,包括 Linux 上.netCore ...

  5. ASP.NETCORE MVC模块化

    ASP.NETCORE MVC模块化编程 前言 记得上一篇博客中跟大家分享的是基于ASP.NETMVC5,实际也就是基于NETFRAMEWORK平台实现的这么一个轻量级插件式框架.那么今天我主要分享的 ...

  6. NETCORE MVC模块化

    NETCORE MVC模块化 ASP.NETCORE MVC模块化编程 前言 记得上一篇博客中跟大家分享的是基于ASP.NETMVC5,实际也就是基于NETFRAMEWORK平台实现的这么一个轻量级插 ...

  7. netcore mvc菜单,角色,权限

    netcore mvc快速开发系统(菜单,角色,权限[精确到按钮])开源 AntMgr https://github.com/yuzd/AntMgr 基于netcore2.0 mvc 开发的 快速搭建 ...

  8. Nancy和MVC的简单对比

    Nancy和MVC的简单对比 在上一篇的.NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy中,简单介绍了Nancy,并写了一个Hello,world.看到大家的评论,都在问Nancy ...

  9. [.Net Core] 在 Mvc 中简单使用日志组件

    在 Mvc 中简单使用日志组件 基于 .Net Core 2.0,本文只是蜻蜓点水,并非深入浅出. 目录 使用内置的日志组件 简单过渡到第三方组件 - NLog 使用内置的日志 下面使用控制器 Hom ...

随机推荐

  1. 转载 | CSS图片下面产生间隙的 6种解决方案

    在进行页面的DIV+CSS排版时,遇到IE6(当然有时Firefox下也会偶遇)浏览器中的图片元素img下出现多余空白的问题绝对是常见的对於 该问题的解决方法也是「见机行事」,根据原因的不同要用不同的 ...

  2. 【java提高】(17)---Java 位运算符

    Java 位运算符 &.|.^.~.<<.>> 以前学过有关java的运算符,不过开发了这么久也很少用过这个.现在由于开发需要,所以现在再来回顾整理下有关java的运算 ...

  3. (二)c#Winform自定义控件-按钮

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  4. C# 复制Excel单元格格式

    本文将介绍通过C# 复制Excel单元格格式的方法,包括复制单元格中的字体.字号.字体加粗.倾斜.单元格背景色.字体颜色.单元格数字格式.单元格文字方向.文字旋转.下划线.单元格对齐方式.单元格边框等 ...

  5. Sqlserver将表中某列数据以符号分成多行

    WITH testtb2 AS ( UNION ALL ) ) ) ) ) PERCENT SUBSTRING(VisitorCard, STA - LENS, LENS) AS OrderReque ...

  6. jmeter之beanshell使用

    beanshell官网:http://www.BeanShell.org/ 一.beanshell介绍 是一种完全符合Java语法规范的轻量级的脚本语言: 相当于一个小巧免费嵌入式的Java源代码解释 ...

  7. [HNOI2008]玩具装箱toy(斜率优化dp)

    前言 这是我写的第一道$dp$斜率优化的题目,$dp$一直都很菜,而且咖啡鸡都说了这是基础的东西,然而看别人对$dp$斜率优化一大堆公式又看不懂就老老实实做几道题目,这个比较实在 描述 给出$n$和$ ...

  8. 纯数据结构Java实现(6/11)(二叉堆&优先队列)

    堆其实也是树结构(或者说基于树结构),一般可以用堆实现优先队列. 二叉堆 堆可以用于实现其他高层数据结构,比如优先队列 而要实现一个堆,可以借助二叉树,其实现称为: 二叉堆 (使用二叉树表示的堆). ...

  9. jmeter+ant生成xml报告

    1.jdk安装 2.jmter安装 3.ant安装 下载apache-ant-1.10.6-bin.zip,直接解压就可使用,和jmeter类似 ant环境变量配置 新建系统变量:ANT_HOME,变 ...

  10. pycharm编辑器简单配置-- 持续更新完善

    目录 python解释器安装.多版本共存等 给pycharm编辑器选择python解释器版本 配置pip仓库地址 方式一:直接修改文件配置 方式二:pycharm配置 方式三:通过临时指定pip仓库地 ...