Realization of functions
- Simple routing system
- Middleware Support
- Simple Filter Support
- Only supports HttpPost, HttpGet
- Use Dotliquid view as the rendering engine
Core implementation
HttpChannel
- Tcp monitor replication request, and in accordance with the data transmission tcp Http protocol data parsed into HttpRequest example, parsed the call processing to the next step HttpHandler
HttpRequest
- Single Http request information, including HttpMethod, Version, Url, HttpHeader, Cookies and other information
HttpResponse
- Http response information
DefaultHttpHandler
Achieve IHttpHandler, responsible for creating Middleware responsibility chain, execution
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
Built middleware, mvc function embodied [Mode FIlter achieved]
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
The easiest route to achieve resolve [URL ---> IController / Method]
Controller own instantiation uses IOC framework implemented netcore
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
Abstract results of the implementation of the MVC analogy IActionResult
Built-in type
HttpStatusCodeResult: return only specific StatusCode, no specific content
JsonResult: return JSON result, content-type: application / json
RedirectResult: 302 return
ViewResult: Use DotLiquid as the view rendering engine
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 Controller Interface
HttpCookie
- cookie action class
IFilter
Filter Interface
public interface IFilter { int Order { get; set; } Task OnActionExecutingAsync(ActionExecuteContext context); Task OnActionExecutedAsync(ActionExecuteContext context); }
other
- This project is just learning to use, if wrong, please point out
- This project is another project EasyProxy subsidiary products, so there is no independent github repository, specific directories for HttpServer
Simple implementation of netcore mvc
Guess you like
Origin www.cnblogs.com/zcode/p/11527485.html
Ranking