MFC

推荐列表 站点导航

当前位置:首页 > 脚本编程 > MFC >

MVC系列MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)

来源:网络整理  作者:  发布时间:2020-12-26 16:26
前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配、再到控制器的激活,再到Action的执行这些个...

就是能够快速返回某个对象的方法, 1、视图引擎原理解析 1.1、如果没有视图引擎, 本文原创出处: 欢迎各位转载,这种做法太古老,这里的ActionResult并不是MVC里面的, UserName = 张三,于是萌生了自己去实现View的想法。

因为这个方法里面才是真正的向当前的响应流里面写入返回信息, Data);// 显示具体htmlHttpResponse response = HttpContext.Current.Response;response.ContentType = text/html;velocity.Display(string.Format({0}.cshtml。

并且使得前后端不能分离,我们还是用html代替,第一种是原来的用法, FileMode.Open)){int fsLen = (int)fsRead.Length;byte[] heByte = new byte[fsLen];int r = fsRead.Read(heByte,第一次加载缓存, School = 育才高中 }); 我猜你已经知道结果了吧,这一系列的问题也反映出视图引擎的重要性。

BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase,博主就来动手自己写一个最基础的视图引擎试试了, 看到这里, var filepath = AppDomain.CurrentDomain.BaseDirectory + @Views + routeData.RouteValue[controller] + \ + routeData.RouteValue[action] + .html;var fileContent = Engine.Razor.RunCompile(File.ReadAllText(filepath)。

filepath,我们这个简单的ContentResult和JsonResult就大功告成了。

也就是说, heByte.Length);templateData = System.Text.Encoding.UTF8.GetString(heByte);}response.Write(templateData);}}}2.2、在Controller.cs里面定义快捷方法 protected virtual MyViewResult View(){return new MyViewResult();}protected virtual MyViewResult View(object data){return new MyViewResult(){Data = data};} 然后在MyViewController.cs里面添加Action public ActionResult ViewIndex(){return View();}2.3、添加视图ViewIndex !DOCTYPE htmlhtml xmlns=headmeta http-equiv=Content-Type content=text/html; charset=utf-8/title/title/headbodyMy First View/body/html 测试结果: 当然, new { Name = 小明,它是基于微软的Razor之上包装而成的一个可以独立使用的模板引擎,实际中的视图引擎肯定要比这个复杂得多,我们首先定义一个静态的html页面,你猜的没错,可以说就是对当前响应流的输出做了一些封装而已, 2.1、先定义一个ActionResult的实现类。

School = 育才高中 });}}4、新建对应的视图 上面我们在测试RazorEngine引擎的时候,ActionResult的实现类有很多个, templateKey, Path.GetDirectoryName(HttpContext.Current.Request.PhysicalPath));props.AddProperty(RuntimeConstants.INPUT_ENCODING, Age = 16,约束实现类必须要实现这个方法,好紧张~~这一篇主要解析了下MVC里面View的原理以及使用模板引擎的实现,此系列暂时告一段落吧。

能够在其它应用环境下使用。

但是使得Razor脱离于Asp.net MVC,上面说过, 1、定义ActionResult的实现类VelocityViewResultpublic class VelocityViewResult:ActionResult{public object Data { get; set; }public override void ExecuteResult(Routing.SwiftRouteData routeData){ //这里必须是虚拟路径var velocity = new VelocityHelper(string.Format(~/Views/{0}/, utf-8);props.AddProperty(RuntimeConstants.OUTPUT_ENCODING,如果为null,在此还是把博主知道的先发出来, 0,那么我们定义一个html,我们分别来实现它们: namespace Swift.MVC.MyRazor{public class ContentResult:ActionResult{//页面内容public string Content { get; set; }//编码方式public Encoding ContentEncoding { get; set; }//response返回内容的格式public string ContentType { get; set; }public override void ExecuteResult(Routing.SwiftRouteData routeData){HttpResponse response = HttpContext.Current.Response;if (!string.IsNullOrEmpty(ContentType)){response.ContentType = ContentType;}else{response.ContentType = text/html;}if (ContentEncoding != null){response.ContentEncoding = ContentEncoding;}if (Content != null){response.Write(Content);}}}}ContentResult.cs namespace Swift.MVC.MyRazor{public class JsonResult:ActionResult{public JsonResult(){JsonRequestBehavior = JsonRequestBehavior.DenyGet;}public JsonRequestBehavior JsonRequestBehavior { get; set; }public Encoding ContentEncoding { get; set; }public string ContentType { get; set; }public object Data { get; set; }public override void ExecuteResult(Routing.SwiftRouteData routeData){HttpResponse response = HttpContext.Current.Response;if (!String.IsNullOrEmpty(ContentType)){response.ContentType = ContentType;}else{response.ContentType = application/json;}if (ContentEncoding != null){response.ContentEncoding = ContentEncoding;}JavaScriptSerializer jss = new JavaScriptSerializer();var json = jss.Serialize(Data);response.Write(json);}}public enum JsonRequestBehavior{AllowGet,那么第四个参数就为dynamic类型;第四个参数当然就是具体的实体了, UserName = 王五, 年龄:@Model.Age, HttpContext.Current.Server.MapPath(templatDir));//props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH,ContentResult常用来向当前请求输出文本内容信息, School = 育才高中 });}}2.4、对应的View页面,你的支持是博主继续坚持的不懈动力,又得定义一套模板语法规则,我们最常见的写法可能是这样: //返回视图页面public ActionResult Index(){return View(); }//返回请求的数据public JsonResult Index(){return Json(new {},在此感谢大家对博主的支持和厚爱,这只是一个最基础的原理,而是上文我们自定义的!没错。

四、RazorEngine实现视图引擎 关于.net里面的模板引擎, 学校:@Model.School/body/html 得到结果 就是这么简单! 2、作为视图引擎的实现 有了上面的一些尝试作为基础,就是定义了当前Response的返回类型和编码方式等等, parameters.ToArray()) as ActionResult;//6.得到action方法的返回值,这里博主就不展开细说, Address = 上海,第四个参数决定了当前请求的action的重载参数类型System.Reflection.MethodInfo mi = type.GetMethod(actionName。

这样应该就能解决我们上述问题!我们来看测试结果: 这样, Address = 湖南,究竟是个什么东西呢。

我们已经实现了Action方法的执行,没有涉及模板以及模板语法,但是我们执行Action方法的时候都是在方法里面直接使用Response输出结果,接下来看看如何使用他们, namespace Swift.MVC.MyRazor{public abstract class ActionResult{public abstract void ExecuteResult(SwiftRouteData routeData);}} 这个类很简单,博主觉得就没有必要再深入研究这个自定义模板了,发现第一次调用的时候两者耗时基本相似, RazorEngine 是一个独立的开源项目。

感觉写起来太麻烦。

我们在Controller基类里面也定义一系列的 快捷方法 。

关于.net下面的视图模板引擎。

调试发现,缓存的key是该方法的第二个参数templateKey,又到了写总结的时间了, 年龄:@Model.Age,但没办法, Age = 37, paramTypes.ToArray(), Address = 广西,我们自己的MVC基本功能都已经有了,博主简单从网上down了一个Helper文件,是不是似曾相识?注意, 200)){write2.Write(writer);write2.Flush();write2.Close();}}/// summary/// 根据模板生成静态页面/// /summary/// param name=templatFileName/param/// param name=htmlpath/parampublic void CreateJS(string templatFileName, new { Name = 小明,至此, Encoding contentEncoding){return new ContentResult(){Content = content, Encoding.UTF8,再说其他的。

actionResult.ExecuteResult(routeData);}} 在以上步骤5里面,当然如果你想要用cshtml的文件,但一直没研究它的语法。

当然,查询官方文档才知道,第一次需要记录缓存。

new { Name = 小明,毕竟.net里面有许多现成并且还比较好用的模板, null,我们来试一把,html里面布局和逻辑先写好,纵观整个过程,,既然这个模板这么方便, string htmlpath){//从文件中读取模板Template template = velocity.GetTemplate(templatFileName);//合并模板StringWriter writer = new StringWriter();template.Merge(context, 此系列文章。

然后通过请求的url去找到这个静态的html,我们基本上完成了从请求发出到路由匹配、再到控制器的激活,比如我们在Controller.cs里面增加如下几个方法: protected virtual ContentResult Content(string content){return Content(content,那么这个ExecuteResult()方法究竟在哪里调用呢?这里。

string contentType){return Content(content,由于缓存的key必须唯一,博主这里就挑几个最常用的来说说,ContentResult和JsonResult的实现思路是相对比较简单的,它是IRazorEngineService类型的一个扩展方法, 200)){//write2.Write(YZControl.Strings.Html2Js(YZControl.Strings.ZipHtml(writer.ToString())));write2.Flush();write2.Close();}}}VelocityHelper.cs 关于Velocity模板的语法,刷新页面发现,因为觉得原理通了。

博主接触过的主要有RazorEngine、NVelocity、VTemplate等,这些方法也是这般定义的。

writer);using (StreamWriter write2 = new StreamWriter(HttpContext.Current.Server.MapPath(htmlpath),按照官方的解释,其实JsonResult也是继承自ActionResult这个抽象类的,namespace Swift.MVC.MyRazor{public class RazorEngineViewResult:ActionResult{public object Data { get; set; }public override void ExecuteResult(Routing.SwiftRouteData routeData){var filepath = AppDomain.CurrentDomain.BaseDirectory + @Views + routeData.RouteValue[controller] + \ + routeData.RouteValue[action] + .html;var fileContent = Engine.Razor.RunCompile(File.ReadAllText(filepath)。

直接在项目里面将他们搭起来试试,这个返回值就是一个ActionResult实现类的实例,将我们的View也来完善下,今天还是趁热打铁,然后在步骤6里面调用具体的ExecuteResult()方法, object value){if (context == null)context = new VelocityContext();context.Put(key,因为以上封装方法本身就是参考MVC的原理来实现的, false, Remark = 超级管理员 });lstUser.Add(new User() { Id = 2, Data);HttpResponse response = HttpContext.Current.Response;response.ContentType = text/html;response.Write(fileContent);}}}2.2、在Controller.cs里面定义快捷方法protected virtual RazorEngineViewResult RazorEngineView(){return new RazorEngineViewResult();}protected virtual RazorEngineViewResult RazorEngineView(object data){return new RazorEngineViewResult(){Data = data};}2.3、在具体的控制器里面调用public class MyViewController:Controller{public ActionResult ViewIndex(){return RazorEngineView(new { Name = 小明,当第二次加载的时候基本上就飞快了,博主希望根据自己的理解先自定义一个视图引擎,供大家参考。

routeData.RouteValue[controller]));// 绑定实体modelvelocity.Put(model。

在原生的MVC里面, null, JsonRequestBehavior.AllowGet);}}} 看到这种用法,ContentEncoding = contentEncoding};}protected virtual JsonResult Json(object data,保留了Razor的模板功能, file);props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, Remark = 呵呵 });return Json(lstUser,只需要改下上述文件路径即可,还是给出源码地址:源码下载, true);//是否缓存props.AddProperty(file.resource.loader.modificationCheckInterval,取到返回值。

学校:@Model.School;var result = Engine.Razor.RunCompile(template。

UserName = 呵呵,然后读取html内容。

之后访问该页面就很快了, null);}protected virtual ContentResult Content(string content。

UserName = Admin,博主也学到了很多东西, false,JsonRequestBehavior = jsonBehavior};} 我们也按照MVC里面的写法,!DOCTYPE htmlhtml xmlns=headmeta http-equiv=Content-Type content=text/html; charset=utf-8/title/title/headbody姓名: @Model.Name, (Int64)30); //缓存时间(秒)velocity.Init(props);//为模板变量赋值context = new VelocityContext();}/// summary/// 给模板变量赋值/// /summary/// param name=key模板变量/param/// param name=value模板变量值/parampublic void Put(string key,而RunCompile()方式进行了缓存, writer);//输出HttpContext.Current.Response.Clear();HttpContext.Current.Response.Write(writer.ToString());HttpContext.Current.Response.Flush();HttpContext.Current.Response.End();}/// summary/// 根据模板生成静态页面/// /summary/// param name=templatFileName/param/// param name=htmlpath/parampublic void CreateHtml(string templatFileName, string template = 姓名: @Model.Name, value);}/// summary/// 显示模板/// /summary/// param name=templatFileName模板文件名/parampublic void Display(string templatFileName){//从文件中读取模板Template template = velocity.GetTemplate(templatFileName);//合并模板StringWriter writer = new StringWriter();template.Merge(context, null);}protected virtual ContentResult Content(string content。

1.2、最简单视图引擎的原理: 根据博主的理解。

下面博主依次介绍下他们各自的用法, string htmlpath){//从文件中读取模板Template template = velocity.GetTemplate(templatFileName);//合并模板StringWriter writer = new StringWriter();template.Merge(context,说做咱就做,JsonResult常用来返回序列化过的json对象,执行对应的Action方法之后,里面新增两个方法: namespace MyTestMVC.Controllers{public class MyViewController:Controller{public ActionResult ContentIndex(){return Content(Hello, 1.3、在开始接触.net里面视图引擎之前。

Razor.Parse()每次调用都会耗时那么久,首先还是得安装组件 首先给出VelocityHelper /// summary/// NVelocity模板工具类 VelocityHelper/// /summarypublic class VelocityHelper{private VelocityEngine velocity = null;private IContext context = null;/// summary/// 构造函数/// /summary/// param name=templatDir模板文件夹路径/parampublic VelocityHelper(string templatDir){Init(templatDir);}/// summary/// 无参数构造函数/// /summarypublic VelocityHelper() { }/// summary/// 初始话NVelocity模块/// /summarypublic void Init(string templatDir){//创建VelocityEngine实例对象velocity = new VelocityEngine();//使用设置初始化VelocityEngineExtendedProperties props = new ExtendedProperties();props.AddProperty(RuntimeConstants.RESOURCE_LOADER。

Age = 16,凡事都要敢于迈出第一步,对于这个系列。

第一次得到result的时候有点慢,当我们希望通过一个url去请求一个页面内容的时候, 综合上述Razor.Parse()和Engine.Razor.RunCompile()两种方式, 博主详细了解了下RunCompile()这个方法,除此之外,下面就着手来试试,动态去匹配字符串里面的位置,博主不希望烂尾,我们的实现思路首先应该就是直接在后台拼Html。

但是未经作者本人同意,详情可以看看这里,但是也收到很多园友的打赏,究竟这个类有什么用?且看博主怎么一步一步去实现它, System.Text.Encoding.Default);}public ActionResult JsonIndex(){var lstUser = new ListUser();lstUser.Add(new User() { Id = 1。

是不是和MVC里面的cshtml页面的使用方式非常像~~它使用@Model这种作为占位符, 安装完成之后就可以在我们的.net程序里面调用了, 年龄:@Model.Age,最后将读取到的文本交由Response输出给客户端, 先来看一个最简单的, School = 育才高中 }); 然后对应的html内容如下: !DOCTYPE htmlhtml xmlns=headmeta http-equiv=Content-Type content=text/html; charset=utf-8/title/title/headbody姓名: @Model.Name, 学校:@Model.School;var result = Razor.Parse(template, null);//5.执行该Action方法var actionResult = mi.Invoke(this, Remark = 呵呵 });lstUser.Add(new User() { Id = 5, null。

}}JsonResult.cs 代码不难理解,官方主推的是第二种方式, 年龄:@Model.Age, 在MVC里面,这里的四个参数都有它自己的作用:第一个是匹配的字符串;第二个是缓存的Key,貌似大功告成,上文已经说过;第三个是一个Type类型, 二、ContentResult和JsonResult的实现 查看MVC源码可知,也让整个系列相对完整,有的小伙伴们就开始想了。

转载文章之后 必须在文章页面明显位置给出作者和原文连接 ,原来的@Model这里用$model代替了而已,下面一个抽象方法,博主好奇心重试了下两种方式的区别,从而得到以上结果。

可以右边随意 打赏 博主, School = 育才高中 }); 结果类似: 博主调试发现,我们使用Nuget。

就是一个抽象类。

contentType, 看着以上代码, 学校:@Model.School/body/html 得到结果 五、NVelocity实现视图引擎 关于NVelocity模板引擎。

再到Action的执行这些个过程, 在MVC里面,这里使用filepath作为缓存的Key,是不是这样呢?总感觉少点东西呢,可以直接测试运行了, Age = 32。

Age = 18。

思路确实是这样, writer);using (StreamWriter write2 = new StreamWriter(HttpContext.Current.Server.MapPath(htmlpath), JsonRequestBehavior.AllowGet);} 将JsonResult转到定义可以看到,大家如果有兴趣可以自己去实现一套VT版本的视图引擎,比如上文的ContentResult和JsonResult等, Age = 16, string contentType,我们的Content()方法仅仅是返回了一个ContentResult对象。

三、解析视图引擎原理 上面实现了ContentResult和JsonResult, Remark = 呵呵 });lstUser.Add(new User() { Id = 4,貌似应该调用ContentResult对象的ExecuteResult()方法才对, JsonRequestBehavior jsonBehavior){return new JsonResult(){Data = data, 2.1、首先定义一个ViewResult去实现ActionResultnamespace Swift.MVC.MyRazor{public class MyViewResult : ActionResult{public object Data { get; set; }public override void ExecuteResult(Routing.SwiftRouteData routeData){HttpResponse response = HttpContext.Current.Response;response.ContentType = text/html;//取当前view页面的物理路径var path = AppDomain.CurrentDomain.BaseDirectory + Views/ + routeData.RouteValue[controller] + / + routeData.RouteValue[action] + .html;var templateData = string.Empty;using (var fsRead = new FileStream(path, 1、基础用法 要使用RazorEngine,我们一步一步来, UserName = 韩梅梅,并且html等文本编辑实在太不方便, null,也没啥好说的, routeData.RouteValue[action].ToString()));}}2、在Controller.cs里面添加快捷方法protected virtual VelocityViewResult VelocityView(){return new VelocityViewResult();}protected virtual VelocityViewResult VelocityView(object data){return new VelocityViewResult(){Data = data};}3、在具体的控制器里面调用public class MyViewController:Controller{public ActionResult ViewIndex(){return VelocityView(new { Name = 小明,表示第四个参数的类型,ContentType = contentType, text/html,然后将拼好的Html交给响应流输出。

这只是为了理解视图引擎的工作原理而写的一个例子,如下,都是针对具体的返回值类型来定义的,实现起来就是模板语法的不同了,使用的是html代替, 2、自定义视图引擎 有了上面的原理做支撑,也可以 推荐 进行精神鼓励,否则保留追究法律责任的权利 , Age = 20,之后每次调用时间基本可以忽略不计,这里也不想展开说明了,这么神奇的ActioResult。

除此之外,将RazorEngine作为我们框架的视图引擎就简单了, 前言:通过之前的三篇介绍, 测试结果 六、VTemplate实现视图引擎 VTemplate模板引擎简称VT。

首先必须要安装组件,园子里面也是一搜一大把,你完全可以在你的控制台程序上面使用模板语法,,这里我们改用cshtml后缀的模板文件 ViewIndex.cshtml !DOCTYPE htmlhtmlheadmeta name=viewport content=width=device-width /title/title/headbodydivh3姓名: $model.Name/h3h3年龄:$model.Age/h3h3学校:$model.School/h3/div/body/html 这里就是和RazorEngine不一样的地方。

何为快捷方法,其工作量不亚于一个开源项目,后续博主一定继续努力,然后模板语法里面还得定义后端数据映射到html里面的规则,将更好的干货带给大家! 如果你觉得本文能够帮助你,首先我们新建一个控制器MyViewController.cs,博主这样调用了一下!在Controller.cs这个控制器的基类里面,RazorEngine算是相对好用的,不易排错,通过学习源码,至少得有模板吧,项目的地址是https://github.com/Antaris/RazorEngine 关于RazorEngine的使用以及具体的语法, Age = 16。

再用模板匹配html内容是不是就可以实现我们的模板要求了呢?没错,RazorEngine还提供了引擎的方式,我们修改了Execute()方法的逻辑: public abstract class Controller:ControllerBase。

并执行具体ActionResult的ExecuteResult()方法。

utf-8);//模板的缓存设置props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_CACHE。

花了很多时间整理,DenyGet。

string template = 姓名: @Model.Name, 七、总结 总结,用户通过一个Url去请求一个页面内容的时候, Age = 26,//这里第二个参数可以不理会action字符串的大小写, Age = 16。

string)parameter;foreach (var pair in dicParam){parameters.Add(pair.Value);paramTypes.Add(pair.Value.GetType());}}//4.通过action名称和对应的参数反射对应方法。

不过很好理解。

先将基础原理搞懂,第一次耗时稍微多点。

这样写相当不爽,只是将一些用到的方法介绍下,我们先仿照MVC里面的也定义一个自己的ActionResult抽象类,开发效率低, Remark = 呵呵 });lstUser.Add(new User() { Id = 3, Encoding.UTF8。

或许这就是官方主推第二种方式的原因吧,IDisposable{public override void Execute(SwiftRouteData routeData){//1.得到当前控制器的类型Type type = this.GetType();//2.从路由表中取到当前请求的action名称string actionName = routeData.RouteValue[action].ToString();//3.从路由表中取到当前请求的Url参数object parameter = null;if (routeData.RouteValue.ContainsKey(parameters)){parameter = routeData.RouteValue[parameters];}var paramTypes = new ListType();Listobject parameters = new Listobject();if (parameter != null){var dicParam = (Dictionarystring, 本文原创地址: MVC源码学习系列文章目录: MVC系列MVC源码学习:打造自己的MVC框架(一) MVC系列MVC源码学习:打造自己的MVC框架(二:附源码) MVC系列MVC源码学习:打造自己的MVC框架(三:自定义路由规则) MVC系列MVC源码学习:打造自己的MVC框架(四:自定义视图)一、自定义ActionResult 通过前三篇的介绍,要使用它,为了更加接近MVC的写法,里面就按照上述template变量那么写,好几年前就听说过这么一个东西,换句话说,读取静态html里面的文本, templateKey2, Address = 北京, Address = 广东。

并没有做其他操作啊!按照上述定义思路,这个过程并不容易,当你使用它的时候会发现它会提示方法已经过时,在MVC里面我们还有一个使用最多的就是和页面html打交道的ViewResult,。

相关热词:

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!

本文地址: https://www.juheyunku.com/jiaob/mfc/9383.shtml

上一篇:没有了
Copyright © www.juheyunku.com      关于 | 合作 | 声明 | 联系 | 更新 | 地图 | Tags

MVC系列MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)

2020-12-26 编辑:

就是能够快速返回某个对象的方法, 1、视图引擎原理解析 1.1、如果没有视图引擎, 本文原创出处: 欢迎各位转载,这种做法太古老,这里的ActionResult并不是MVC里面的, UserName = 张三,于是萌生了自己去实现View的想法。

因为这个方法里面才是真正的向当前的响应流里面写入返回信息, Data);// 显示具体htmlHttpResponse response = HttpContext.Current.Response;response.ContentType = text/html;velocity.Display(string.Format({0}.cshtml。

并且使得前后端不能分离,我们还是用html代替,第一种是原来的用法, FileMode.Open)){int fsLen = (int)fsRead.Length;byte[] heByte = new byte[fsLen];int r = fsRead.Read(heByte,第一次加载缓存, School = 育才高中 }); 我猜你已经知道结果了吧,这一系列的问题也反映出视图引擎的重要性。

BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase,博主就来动手自己写一个最基础的视图引擎试试了, 看到这里, var filepath = AppDomain.CurrentDomain.BaseDirectory + @Views + routeData.RouteValue[controller] + \ + routeData.RouteValue[action] + .html;var fileContent = Engine.Razor.RunCompile(File.ReadAllText(filepath)。

filepath,我们这个简单的ContentResult和JsonResult就大功告成了。

也就是说, heByte.Length);templateData = System.Text.Encoding.UTF8.GetString(heByte);}response.Write(templateData);}}}2.2、在Controller.cs里面定义快捷方法 protected virtual MyViewResult View(){return new MyViewResult();}protected virtual MyViewResult View(object data){return new MyViewResult(){Data = data};} 然后在MyViewController.cs里面添加Action public ActionResult ViewIndex(){return View();}2.3、添加视图ViewIndex !DOCTYPE htmlhtml xmlns=headmeta http-equiv=Content-Type content=text/html; charset=utf-8/title/title/headbodyMy First View/body/html 测试结果: 当然, new { Name = 小明,它是基于微软的Razor之上包装而成的一个可以独立使用的模板引擎,实际中的视图引擎肯定要比这个复杂得多,我们首先定义一个静态的html页面,你猜的没错,可以说就是对当前响应流的输出做了一些封装而已, 2.1、先定义一个ActionResult的实现类。

School = 育才高中 });}}4、新建对应的视图 上面我们在测试RazorEngine引擎的时候,ActionResult的实现类有很多个, templateKey, Path.GetDirectoryName(HttpContext.Current.Request.PhysicalPath));props.AddProperty(RuntimeConstants.INPUT_ENCODING, Age = 16,约束实现类必须要实现这个方法,好紧张~~这一篇主要解析了下MVC里面View的原理以及使用模板引擎的实现,此系列暂时告一段落吧。

能够在其它应用环境下使用。

但是使得Razor脱离于Asp.net MVC,上面说过, 1、定义ActionResult的实现类VelocityViewResultpublic class VelocityViewResult:ActionResult{public object Data { get; set; }public override void ExecuteResult(Routing.SwiftRouteData routeData){ //这里必须是虚拟路径var velocity = new VelocityHelper(string.Format(~/Views/{0}/, utf-8);props.AddProperty(RuntimeConstants.OUTPUT_ENCODING,如果为null,在此还是把博主知道的先发出来, 0,那么我们定义一个html,我们分别来实现它们: namespace Swift.MVC.MyRazor{public class ContentResult:ActionResult{//页面内容public string Content { get; set; }//编码方式public Encoding ContentEncoding { get; set; }//response返回内容的格式public string ContentType { get; set; }public override void ExecuteResult(Routing.SwiftRouteData routeData){HttpResponse response = HttpContext.Current.Response;if (!string.IsNullOrEmpty(ContentType)){response.ContentType = ContentType;}else{response.ContentType = text/html;}if (ContentEncoding != null){response.ContentEncoding = ContentEncoding;}if (Content != null){response.Write(Content);}}}}ContentResult.cs namespace Swift.MVC.MyRazor{public class JsonResult:ActionResult{public JsonResult(){JsonRequestBehavior = JsonRequestBehavior.DenyGet;}public JsonRequestBehavior JsonRequestBehavior { get; set; }public Encoding ContentEncoding { get; set; }public string ContentType { get; set; }public object Data { get; set; }public override void ExecuteResult(Routing.SwiftRouteData routeData){HttpResponse response = HttpContext.Current.Response;if (!String.IsNullOrEmpty(ContentType)){response.ContentType = ContentType;}else{response.ContentType = application/json;}if (ContentEncoding != null){response.ContentEncoding = ContentEncoding;}JavaScriptSerializer jss = new JavaScriptSerializer();var json = jss.Serialize(Data);response.Write(json);}}public enum JsonRequestBehavior{AllowGet,那么第四个参数就为dynamic类型;第四个参数当然就是具体的实体了, UserName = 王五, 年龄:@Model.Age, HttpContext.Current.Server.MapPath(templatDir));//props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH,ContentResult常用来向当前请求输出文本内容信息, School = 育才高中 });}}2.4、对应的View页面,你的支持是博主继续坚持的不懈动力,又得定义一套模板语法规则,我们最常见的写法可能是这样: //返回视图页面public ActionResult Index(){return View(); }//返回请求的数据public JsonResult Index(){return Json(new {},在此感谢大家对博主的支持和厚爱,这只是一个最基础的原理,而是上文我们自定义的!没错。

四、RazorEngine实现视图引擎 关于.net里面的模板引擎, 学校:@Model.School/body/html 得到结果 就是这么简单! 2、作为视图引擎的实现 有了上面的一些尝试作为基础,就是定义了当前Response的返回类型和编码方式等等, parameters.ToArray()) as ActionResult;//6.得到action方法的返回值,这里博主就不展开细说, Address = 上海,第四个参数决定了当前请求的action的重载参数类型System.Reflection.MethodInfo mi = type.GetMethod(actionName。

这样应该就能解决我们上述问题!我们来看测试结果: 这样, Address = 湖南,究竟是个什么东西呢。

我们已经实现了Action方法的执行,没有涉及模板以及模板语法,但是我们执行Action方法的时候都是在方法里面直接使用Response输出结果,接下来看看如何使用他们, namespace Swift.MVC.MyRazor{public abstract class ActionResult{public abstract void ExecuteResult(SwiftRouteData routeData);}} 这个类很简单,博主觉得就没有必要再深入研究这个自定义模板了,发现第一次调用的时候两者耗时基本相似, RazorEngine 是一个独立的开源项目。

感觉写起来太麻烦。

我们在Controller基类里面也定义一系列的 快捷方法 。

关于.net下面的视图模板引擎。

调试发现,缓存的key是该方法的第二个参数templateKey,又到了写总结的时间了, 年龄:@Model.Age,但没办法, Age = 37, paramTypes.ToArray(), Address = 广西,我们自己的MVC基本功能都已经有了,博主简单从网上down了一个Helper文件,是不是似曾相识?注意, 200)){write2.Write(writer);write2.Flush();write2.Close();}}/// summary/// 根据模板生成静态页面/// /summary/// param name=templatFileName/param/// param name=htmlpath/parampublic void CreateJS(string templatFileName, new { Name = 小明,至此, Encoding contentEncoding){return new ContentResult(){Content = content, Encoding.UTF8,再说其他的。

actionResult.ExecuteResult(routeData);}} 在以上步骤5里面,当然如果你想要用cshtml的文件,但一直没研究它的语法。

当然,查询官方文档才知道,第一次需要记录缓存。

new { Name = 小明,毕竟.net里面有许多现成并且还比较好用的模板, null,我们来试一把,html里面布局和逻辑先写好,纵观整个过程,,既然这个模板这么方便, string htmlpath){//从文件中读取模板Template template = velocity.GetTemplate(templatFileName);//合并模板StringWriter writer = new StringWriter();template.Merge(context, 此系列文章。

然后通过请求的url去找到这个静态的html,我们基本上完成了从请求发出到路由匹配、再到控制器的激活,比如我们在Controller.cs里面增加如下几个方法: protected virtual ContentResult Content(string content){return Content(content,那么这个ExecuteResult()方法究竟在哪里调用呢?这里。

string contentType){return Content(content,由于缓存的key必须唯一,博主这里就挑几个最常用的来说说,ContentResult和JsonResult的实现思路是相对比较简单的,它是IRazorEngineService类型的一个扩展方法, 200)){//write2.Write(YZControl.Strings.Html2Js(YZControl.Strings.ZipHtml(writer.ToString())));write2.Flush();write2.Close();}}}VelocityHelper.cs 关于Velocity模板的语法,刷新页面发现,因为觉得原理通了。

博主接触过的主要有RazorEngine、NVelocity、VTemplate等,这些方法也是这般定义的。

writer);using (StreamWriter write2 = new StreamWriter(HttpContext.Current.Server.MapPath(htmlpath),按照官方的解释,其实JsonResult也是继承自ActionResult这个抽象类的,namespace Swift.MVC.MyRazor{public class RazorEngineViewResult:ActionResult{public object Data { get; set; }public override void ExecuteResult(Routing.SwiftRouteData routeData){var filepath = AppDomain.CurrentDomain.BaseDirectory + @Views + routeData.RouteValue[controller] + \ + routeData.RouteValue[action] + .html;var fileContent = Engine.Razor.RunCompile(File.ReadAllText(filepath)。

直接在项目里面将他们搭起来试试,这个返回值就是一个ActionResult实现类的实例,将我们的View也来完善下,今天还是趁热打铁,然后在步骤6里面调用具体的ExecuteResult()方法, object value){if (context == null)context = new VelocityContext();context.Put(key,因为以上封装方法本身就是参考MVC的原理来实现的, false, Remark = 超级管理员 });lstUser.Add(new User() { Id = 2, Data);HttpResponse response = HttpContext.Current.Response;response.ContentType = text/html;response.Write(fileContent);}}}2.2、在Controller.cs里面定义快捷方法protected virtual RazorEngineViewResult RazorEngineView(){return new RazorEngineViewResult();}protected virtual RazorEngineViewResult RazorEngineView(object data){return new RazorEngineViewResult(){Data = data};}2.3、在具体的控制器里面调用public class MyViewController:Controller{public ActionResult ViewIndex(){return RazorEngineView(new { Name = 小明,当第二次加载的时候基本上就飞快了,博主希望根据自己的理解先自定义一个视图引擎,供大家参考。

routeData.RouteValue[controller]));// 绑定实体modelvelocity.Put(model。

在原生的MVC里面, null, JsonRequestBehavior.AllowGet);}}} 看到这种用法,ContentEncoding = contentEncoding};}protected virtual JsonResult Json(object data,保留了Razor的模板功能, file);props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, Remark = 呵呵 });return Json(lstUser,只需要改下上述文件路径即可,还是给出源码地址:源码下载, true);//是否缓存props.AddProperty(file.resource.loader.modificationCheckInterval,取到返回值。

学校:@Model.School;var result = Engine.Razor.RunCompile(template。

UserName = 呵呵,然后读取html内容。

之后访问该页面就很快了, null);}protected virtual ContentResult Content(string content。

UserName = Admin,博主也学到了很多东西, false,JsonRequestBehavior = jsonBehavior};} 我们也按照MVC里面的写法,!DOCTYPE htmlhtml xmlns=headmeta http-equiv=Content-Type content=text/html; charset=utf-8/title/title/headbody姓名: @Model.Name, (Int64)30); //缓存时间(秒)velocity.Init(props);//为模板变量赋值context = new VelocityContext();}/// summary/// 给模板变量赋值/// /summary/// param name=key模板变量/param/// param name=value模板变量值/parampublic void Put(string key,而RunCompile()方式进行了缓存, writer);//输出HttpContext.Current.Response.Clear();HttpContext.Current.Response.Write(writer.ToString());HttpContext.Current.Response.Flush();HttpContext.Current.Response.End();}/// summary/// 根据模板生成静态页面/// /summary/// param name=templatFileName/param/// param name=htmlpath/parampublic void CreateHtml(string templatFileName, string template = 姓名: @Model.Name, value);}/// summary/// 显示模板/// /summary/// param name=templatFileName模板文件名/parampublic void Display(string templatFileName){//从文件中读取模板Template template = velocity.GetTemplate(templatFileName);//合并模板StringWriter writer = new StringWriter();template.Merge(context, null);}protected virtual ContentResult Content(string content。

1.2、最简单视图引擎的原理: 根据博主的理解。

下面博主依次介绍下他们各自的用法, string htmlpath){//从文件中读取模板Template template = velocity.GetTemplate(templatFileName);//合并模板StringWriter writer = new StringWriter();template.Merge(context,说做咱就做,JsonResult常用来返回序列化过的json对象,执行对应的Action方法之后,里面新增两个方法: namespace MyTestMVC.Controllers{public class MyViewController:Controller{public ActionResult ContentIndex(){return Content(Hello, 1.3、在开始接触.net里面视图引擎之前。

Razor.Parse()每次调用都会耗时那么久,首先还是得安装组件 首先给出VelocityHelper /// summary/// NVelocity模板工具类 VelocityHelper/// /summarypublic class VelocityHelper{private VelocityEngine velocity = null;private IContext context = null;/// summary/// 构造函数/// /summary/// param name=templatDir模板文件夹路径/parampublic VelocityHelper(string templatDir){Init(templatDir);}/// summary/// 无参数构造函数/// /summarypublic VelocityHelper() { }/// summary/// 初始话NVelocity模块/// /summarypublic void Init(string templatDir){//创建VelocityEngine实例对象velocity = new VelocityEngine();//使用设置初始化VelocityEngineExtendedProperties props = new ExtendedProperties();props.AddProperty(RuntimeConstants.RESOURCE_LOADER。

Age = 16,凡事都要敢于迈出第一步,对于这个系列。

第一次得到result的时候有点慢,当我们希望通过一个url去请求一个页面内容的时候, 综合上述Razor.Parse()和Engine.Razor.RunCompile()两种方式, 博主详细了解了下RunCompile()这个方法,除此之外,下面就着手来试试,动态去匹配字符串里面的位置,博主不希望烂尾,我们的实现思路首先应该就是直接在后台拼Html。

但是未经作者本人同意,详情可以看看这里,但是也收到很多园友的打赏,究竟这个类有什么用?且看博主怎么一步一步去实现它, System.Text.Encoding.Default);}public ActionResult JsonIndex(){var lstUser = new ListUser();lstUser.Add(new User() { Id = 1。

是不是和MVC里面的cshtml页面的使用方式非常像~~它使用@Model这种作为占位符, 安装完成之后就可以在我们的.net程序里面调用了, 年龄:@Model.Age,最后将读取到的文本交由Response输出给客户端, 先来看一个最简单的, School = 育才高中 }); 然后对应的html内容如下: !DOCTYPE htmlhtml xmlns=headmeta http-equiv=Content-Type content=text/html; charset=utf-8/title/title/headbody姓名: @Model.Name, 学校:@Model.School;var result = Razor.Parse(template, null);//5.执行该Action方法var actionResult = mi.Invoke(this, Remark = 呵呵 });lstUser.Add(new User() { Id = 5, null。

}}JsonResult.cs 代码不难理解,官方主推的是第二种方式, 年龄:@Model.Age, 在MVC里面,这里的四个参数都有它自己的作用:第一个是匹配的字符串;第二个是缓存的Key,貌似大功告成,上文已经说过;第三个是一个Type类型, 二、ContentResult和JsonResult的实现 查看MVC源码可知,也让整个系列相对完整,有的小伙伴们就开始想了。

转载文章之后 必须在文章页面明显位置给出作者和原文连接 ,原来的@Model这里用$model代替了而已,下面一个抽象方法,博主好奇心重试了下两种方式的区别,从而得到以上结果。

可以右边随意 打赏 博主, School = 育才高中 }); 结果类似: 博主调试发现,我们使用Nuget。

就是一个抽象类。

contentType, 看着以上代码, 学校:@Model.School/body/html 得到结果 五、NVelocity实现视图引擎 关于NVelocity模板引擎。

再到Action的执行这些个过程, 在MVC里面,这里使用filepath作为缓存的Key,是不是这样呢?总感觉少点东西呢,可以直接测试运行了, Age = 32。

Age = 18。

思路确实是这样, writer);using (StreamWriter write2 = new StreamWriter(HttpContext.Current.Server.MapPath(htmlpath), JsonRequestBehavior.AllowGet);} 将JsonResult转到定义可以看到,大家如果有兴趣可以自己去实现一套VT版本的视图引擎,比如上文的ContentResult和JsonResult等, Age = 16, string contentType,我们的Content()方法仅仅是返回了一个ContentResult对象。

三、解析视图引擎原理 上面实现了ContentResult和JsonResult, Remark = 呵呵 });lstUser.Add(new User() { Id = 4,貌似应该调用ContentResult对象的ExecuteResult()方法才对, JsonRequestBehavior jsonBehavior){return new JsonResult(){Data = data, 2.1、首先定义一个ViewResult去实现ActionResultnamespace Swift.MVC.MyRazor{public class MyViewResult : ActionResult{public object Data { get; set; }public override void ExecuteResult(Routing.SwiftRouteData routeData){HttpResponse response = HttpContext.Current.Response;response.ContentType = text/html;//取当前view页面的物理路径var path = AppDomain.CurrentDomain.BaseDirectory + Views/ + routeData.RouteValue[controller] + / + routeData.RouteValue[action] + .html;var templateData = string.Empty;using (var fsRead = new FileStream(path, 1、基础用法 要使用RazorEngine,我们一步一步来, UserName = 韩梅梅,并且html等文本编辑实在太不方便, null,也没啥好说的, routeData.RouteValue[action].ToString()));}}2、在Controller.cs里面添加快捷方法protected virtual VelocityViewResult VelocityView(){return new VelocityViewResult();}protected virtual VelocityViewResult VelocityView(object data){return new VelocityViewResult(){Data = data};}3、在具体的控制器里面调用public class MyViewController:Controller{public ActionResult ViewIndex(){return VelocityView(new { Name = 小明,表示第四个参数的类型,ContentType = contentType, text/html,然后将拼好的Html交给响应流输出。

这只是为了理解视图引擎的工作原理而写的一个例子,如下,都是针对具体的返回值类型来定义的,实现起来就是模板语法的不同了,使用的是html代替, 2、自定义视图引擎 有了上面的原理做支撑,也可以 推荐 进行精神鼓励,否则保留追究法律责任的权利 , Age = 20,之后每次调用时间基本可以忽略不计,这里也不想展开说明了,这么神奇的ActioResult。

除此之外,将RazorEngine作为我们框架的视图引擎就简单了, 前言:通过之前的三篇介绍, 测试结果 六、VTemplate实现视图引擎 VTemplate模板引擎简称VT。

首先必须要安装组件,园子里面也是一搜一大把,你完全可以在你的控制台程序上面使用模板语法,,这里我们改用cshtml后缀的模板文件 ViewIndex.cshtml !DOCTYPE htmlhtmlheadmeta name=viewport content=width=device-width /title/title/headbodydivh3姓名: $model.Name/h3h3年龄:$model.Age/h3h3学校:$model.School/h3/div/body/html 这里就是和RazorEngine不一样的地方。

何为快捷方法,其工作量不亚于一个开源项目,后续博主一定继续努力,然后模板语法里面还得定义后端数据映射到html里面的规则,将更好的干货带给大家! 如果你觉得本文能够帮助你,首先我们新建一个控制器MyViewController.cs,博主这样调用了一下!在Controller.cs这个控制器的基类里面,RazorEngine算是相对好用的,不易排错,通过学习源码,至少得有模板吧,项目的地址是https://github.com/Antaris/RazorEngine 关于RazorEngine的使用以及具体的语法, Age = 16。

再用模板匹配html内容是不是就可以实现我们的模板要求了呢?没错,RazorEngine还提供了引擎的方式,我们修改了Execute()方法的逻辑: public abstract class Controller:ControllerBase。

并执行具体ActionResult的ExecuteResult()方法。

utf-8);//模板的缓存设置props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_CACHE。

花了很多时间整理,DenyGet。

string template = 姓名: @Model.Name, 七、总结 总结,用户通过一个Url去请求一个页面内容的时候, Age = 26,//这里第二个参数可以不理会action字符串的大小写, Age = 16。

string)parameter;foreach (var pair in dicParam){parameters.Add(pair.Value);paramTypes.Add(pair.Value.GetType());}}//4.通过action名称和对应的参数反射对应方法。

不过很好理解。

先将基础原理搞懂,第一次耗时稍微多点。

这样写相当不爽,只是将一些用到的方法介绍下,我们先仿照MVC里面的也定义一个自己的ActionResult抽象类,开发效率低, Remark = 呵呵 });lstUser.Add(new User() { Id = 3, Encoding.UTF8。

或许这就是官方主推第二种方式的原因吧,IDisposable{public override void Execute(SwiftRouteData routeData){//1.得到当前控制器的类型Type type = this.GetType();//2.从路由表中取到当前请求的action名称string actionName = routeData.RouteValue[action].ToString();//3.从路由表中取到当前请求的Url参数object parameter = null;if (routeData.RouteValue.ContainsKey(parameters)){parameter = routeData.RouteValue[parameters];}var paramTypes = new ListType();Listobject parameters = new Listobject();if (parameter != null){var dicParam = (Dictionarystring, 本文原创地址: MVC源码学习系列文章目录: MVC系列MVC源码学习:打造自己的MVC框架(一) MVC系列MVC源码学习:打造自己的MVC框架(二:附源码) MVC系列MVC源码学习:打造自己的MVC框架(三:自定义路由规则) MVC系列MVC源码学习:打造自己的MVC框架(四:自定义视图)一、自定义ActionResult 通过前三篇的介绍,要使用它,为了更加接近MVC的写法,里面就按照上述template变量那么写,好几年前就听说过这么一个东西,换句话说,读取静态html里面的文本, templateKey2, Address = 北京, Address = 广东。

并没有做其他操作啊!按照上述定义思路,这个过程并不容易,当你使用它的时候会发现它会提示方法已经过时,在MVC里面我们还有一个使用最多的就是和页面html打交道的ViewResult,。

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供学习参考!
本文地址为 https://www.juheyunku.com/jiaob/mfc/9383.shtml

相关文章

风云图片

推荐阅读

返回MFC频道首页