netcore mvc 的简单实现
实现的功能
- 简单的路由系统
- 支持中间件
- 简单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 的简单实现的更多相关文章
- .NetCore MVC中的路由(2)在路由中使用约束
p { margin-bottom: 0.25cm; direction: ltr; color: #000000; line-height: 120%; orphans: 2; widows: 2 ...
- .NetCore MVC中的路由(1)路由配置基础
.NetCore MVC中的路由(1)路由配置基础 0x00 路由在MVC中起到的作用 前段时间一直忙于别的事情,终于搞定了继续学习.NetCore.这次学习的主题是MVC中的路由.路由是所有MVC框 ...
- .netcore mvc docker环境jenkins一键部署(DevOps)
[前言] DevOps方面的文章很早之前就想分享了,挤出一点时间把前段时间搭建的一些提高开发效率的东西给大家分享一下吧. 本文介绍了一个.netcore mvc web项目,从项目push到githu ...
- windows 下开发的 .netCore MVC 部署到 Linux(Mint)
这两天在公司跟同事偶然聊到 .netCore,说到一些趋势什么的.但是说来说去自己也没试过在Linux 机子上部署过,所以就试一下. 尝试之前也在网上看了一些文章,包括 Linux 上.netCore ...
- ASP.NETCORE MVC模块化
ASP.NETCORE MVC模块化编程 前言 记得上一篇博客中跟大家分享的是基于ASP.NETMVC5,实际也就是基于NETFRAMEWORK平台实现的这么一个轻量级插件式框架.那么今天我主要分享的 ...
- NETCORE MVC模块化
NETCORE MVC模块化 ASP.NETCORE MVC模块化编程 前言 记得上一篇博客中跟大家分享的是基于ASP.NETMVC5,实际也就是基于NETFRAMEWORK平台实现的这么一个轻量级插 ...
- netcore mvc菜单,角色,权限
netcore mvc快速开发系统(菜单,角色,权限[精确到按钮])开源 AntMgr https://github.com/yuzd/AntMgr 基于netcore2.0 mvc 开发的 快速搭建 ...
- Nancy和MVC的简单对比
Nancy和MVC的简单对比 在上一篇的.NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy中,简单介绍了Nancy,并写了一个Hello,world.看到大家的评论,都在问Nancy ...
- [.Net Core] 在 Mvc 中简单使用日志组件
在 Mvc 中简单使用日志组件 基于 .Net Core 2.0,本文只是蜻蜓点水,并非深入浅出. 目录 使用内置的日志组件 简单过渡到第三方组件 - NLog 使用内置的日志 下面使用控制器 Hom ...
随机推荐
- HDU 4635 (完全图 和 有向图缩点)
题目链接:HDU 4635 题目大意: 给你一个有向图,加有向边,使得这个图是简单有向图.问你最多加多少条有向边. 简单有向图: 1.不存在有向重边. 2.不存在图循环.(注意是不存在 “图” 循环 ...
- docker-compose 综合训练
Docker-compose综合训练 一. 实验目的: 熟悉Docker-compose的基本工作原理: 熟悉Docker-compose安装 熟悉Docker compose命令基础 熟悉Docke ...
- Navicat连接MYsql报错
在Windows中安装mysql8后,使用Navicat连接数据库是出现“ Client does not support authentication protocol requested by s ...
- python2.7官方文档阅读笔记
官方地址:https://docs.python.org/2.7/tutorial/index.html 本笔记只记录本人不熟悉的知识点 The Python Tutorial Index 1 Whe ...
- 《机器学习基石》---VC维
1 VC维的定义 VC维其实就是第一个break point的之前的样本容量.标准定义是:对一个假设空间,如果存在N个样本能够被假设空间中的h按所有可能的2的N次方种形式分开,则称该假设空间能够把N个 ...
- RedHat 6.5换源
https://wenku.baidu.com/view/5b87fb42c77da26924c5b03b.html
- .Net 连接FTP下载文件报错:System.InvalidOperationException: The requested FTP command is not supported when using HTTP proxy
系统环境: Windows + .Net Framework 4.0 问题描述: C#连接FTP下载文件时,在部分电脑上有异常报错,在一部分电脑上是正常的:异常报错的信息:System.Inval ...
- 02 http和https协议
1. HTTP协议 简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写, 是用于从万维网(WWW:World Wide Web )服务器传输超文本到本 ...
- vs中代码的发行以及图标的添加
发布代码,将Debug改成Release 在属性代码生成中找到运行库将多线程MD改成MT应用(使文件适用于普遍的电脑) 重新生成解决方案然后就可以在项目文件夹中找到Release底下的.exe文件(可 ...
- wav封装格式
wav文件格式作为一种常用的多媒体音频文件格式,其由MS在1991年8月在Windows 3.1上推出,文件扩展名为WAV,是WaveFom的简写.通常存储未压缩的pcm数据,也可存储压缩的pcm数据 ...