第四篇 基于.net搭建热插拔式web框架(RazorEngine实现)_html/css_WEB-ITnose
在开头也是先给大家道个歉,由于最近准备婚事导致这篇文章耽误了许久,同时也谢谢老婆大人对我的支持。
回顾上篇文章,我们重造了一个controller,这个controller中用到了视图引擎,我们的视图引擎虽然也叫Razor,但此Razor非mvc中的Razor,MVC中的Razor同样依赖于HttpContext,我们实现的Razor借用 RazorEngine 。关于 RazorEngine的更多介绍请参阅http://antaris.github.io/RazorEngine/。
在上篇文章中无论是View方法还是PartialView方法,都用到了CompileView对象,我们先来看一下 CompileView类的实现。
/// <summary> /// 视图编译类 /// </summary> public class CompileView { private static Regex layoutEx = new Regex("Layout\\s*=\\s*@?\"(\\S*)\";");//匹配视图中的layout static InvalidatingCachingProvider cache = new InvalidatingCachingProvider(); static FileSystemWatcher m_Watcher = new FileSystemWatcher(); static CompileView() { var config = new TemplateServiceConfiguration(); config.BaseTemplateType = typeof(HuberImplementingTemplateBase<>); config.ReferenceResolver = new HuberReferenceResolver(); config.CachingProvider = cache; cache.InvalidateAll(); Engine.Razor = RazorEngineService.Create(config); //添加文件修改监控,以便在cshtml文件修改时重新编译该文件 m_Watcher.Path = HuberVariable.CurWebDir; m_Watcher.IncludeSubdirectories = true; m_Watcher.Filter = "*.*"; m_Watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName; m_Watcher.Created += new FileSystemEventHandler(OnChanged); m_Watcher.Changed += new FileSystemEventHandler(OnChanged); m_Watcher.Deleted += new FileSystemEventHandler(OnChanged); m_Watcher.EnableRaisingEvents = true; } //当视图被修改后清除缓存 private static void OnChanged(object sender, FileSystemEventArgs e) { if (e.FullPath.EndsWith(".cshtml")) { string s = e.FullPath.Replace(HuberVariable.CurWebDir, "/"); var key = Engine.Razor.GetKey(s); cache.InvalidateCache(key); } } public CompileView() { } public string RunCompile(ITemplateKey key, Type modelType, object model, DynamicViewBag viewBag) { //判断唯一视图的缓存 string path = (HuberVariable.CurWebDir + key.Name).Replace(@"\\", @"\"); ICompiledTemplate cacheTemplate; cache.TryRetrieveTemplate(key, null, out cacheTemplate); if (cacheTemplate == null || !cacheTemplate.Key.Name.Trim().Equals(key.Name.Trim())) { CompileViewAndLayout(key, null, model, viewBag); } //当缓存存在返回结果 return Engine.Razor.RunCompile(key, null, model, viewBag); } /// <summary> /// 编译视图和层layout /// </summary> /// <param name="key">视图的唯一路径</param> /// <param name="modelType">视图类型 :视图/layout</param> /// <param name="model">页面 MODEL</param> /// <param name="viewBag">viewBag</param> public void CompileViewAndLayout(ITemplateKey key, Type modelType, object model, DynamicViewBag viewBag) { //获取视图 string FullPath = (HuberVariable.CurWebDir + key.Name.Replace("/", @"\")).Replace(@"\\", @"\"); string content = System.IO.File.ReadAllText(FullPath); //匹配layout var matchs = layoutEx.Matches(content); string layoutPath = string.Empty; if (matchs != null) { foreach (Match m in matchs) { layoutPath = m.Groups[1].Value; } } if (layoutPath != string.Empty) { //添加layout到模板 string FullLayoutPath = (HuberVariable.CurWebDir + layoutPath.Replace("/", @"\")).Replace(@"\\", @"\"); if (File.Exists(FullLayoutPath)) { ITemplateKey layoutKey = Engine.Razor.GetKey(layoutPath, ResolveType.Layout); CompileViewAndLayout(layoutKey, null, model, viewBag); } } if (key.TemplateType == ResolveType.Layout) { Engine.Razor.AddTemplate(key, content); } else { //编译视图 Engine.Razor.RunCompile(content, key, null, model); } } }
InvalidatingCachingProvider是RazorEngine对视图文件编译结果的一种缓存策略,RazorEngine提供的缓存策略还有DefaultCachingProvider,也可以自己实现一种缓存策略只要继承ICachingProvider。
HuberImplementingTemplateBase:我们自定义的一种Razor模板标签,如“@Html.Raw”,这个例子也可以在RazorEngine官方文档中找到。我们还可以按照规则定义更多用法,下边是我的一些实现:
1 /// <summary>页面帮助类 2 /// A simple helper demonstrating the @Html.Raw 3 /// </summary> 4 /// <typeparam name="T"></typeparam> 5 public class HuberImplementingTemplateBase<T> : TemplateBase<T> 6 { 7 /// <summary> 8 /// A simple helper demonstrating the @Html.Raw 9 /// </summary> 10 public HuberImplementingTemplateBase() 11 { 12 Html = new RazorHtmlHelper(); 13 } 14 15 /// <summary> 16 /// A simple helper demonstrating the @Html.Raw 17 /// 18 /// </summary> 19 public RazorHtmlHelper Html { get; set; } 20 21 } 22 23 public class RazorHtmlHelper 24 { 25 26 /// <summary> 27 /// 调用Action视图 28 /// </summary> 29 /// <param name="actionName">action方法名称</param> 30 /// <param name="controllerName">控制器名称</param> 31 /// <returns></returns> 32 public IEncodedString Action(string actionName, string controllerName) 33 { 34 return Action(actionName, controllerName, new { }); 35 36 } 37 38 /// <summary> 39 /// 调用Action视图 40 /// </summary> 41 /// <param name="actionName"></param> 42 /// <param name="controllerName"></param> 43 /// <param name="routeValues">传入参数</param> 44 /// <returns></returns> 45 public IEncodedString Action(string actionName, string controllerName, object routeValues) 46 { 47 RefRequestEntity paras = SetParamValue(routeValues); 48 49 var t = HuberHttpModule.CurDomainAssembly.GetType(HuberHttpModule.CurDomainAssemblyName + ".Controllers." + controllerName + "Controller"); 50 var m = t.GetMethod(actionName); 51 object dObj = Activator.CreateInstance(t); 52 object result = m.Invoke(dObj, new object[] { paras }); 53 return new RawString((result as RefRespondEntity).ResultContext.ToString()); 54 } 55 56 /// <summary> 57 /// 根据model设置传入参数 58 /// </summary> 59 /// <param name="routeValues"></param> 60 /// <returns></returns> 61 private static RefRequestEntity SetParamValue(object routeValues) 62 { 63 RefRequestEntity paras = new RefRequestEntity(); 64 65 Type t1 = routeValues.GetType(); 66 PropertyInfo[] pis = t1.GetProperties(); 67 foreach (PropertyInfo pi in pis) 68 { 69 paras.Request.Add(pi.Name, pi.GetValue(routeValues)); 70 71 } 72 return paras; 73 } 74 75 76 public IEncodedString RenderAction(string actionName, string controllerName) 77 { 78 return Action(actionName, controllerName, new { }); 79 } 80 81 public IEncodedString RenderAction(string actionName, string controllerName, object routeValues) 82 { 83 return Action(actionName, controllerName, routeValues); 84 } 85 86 public IEncodedString RenderPartial(string partialViewName, string controllerName) 87 { 88 return RenderPartial(partialViewName, controllerName, new { }, new DynamicViewBag()); 89 } 90 91 // Renders the partial view with the given view data and, implicitly, the given view data's model 92 public IEncodedString RenderPartial(string partialViewName, string controllerName, DynamicViewBag ViewBag) 93 { 94 return RenderPartial(partialViewName, controllerName, new { }, ViewBag); 95 } 96 97 // Renders the partial view with an empty view data and the given model 98 public IEncodedString RenderPartial(string partialViewName, string controllerName, object model) 99 {100 return RenderPartial(partialViewName, controllerName, model, new DynamicViewBag());101 }102 103 104 // Renders the partial view with a copy of the given view data plus the given model105 /// <summary>106 /// 部分视图107 /// </summary>108 /// <param name="partialViewName">部分视图名称</param>109 /// <param name="controllerName">控制器名称</param>110 /// <param name="model"> model</param>111 /// <param name="ViewBag">ViewBag</param>112 /// <returns></returns>113 public IEncodedString RenderPartial(string partialViewName, string controllerName, object model, DynamicViewBag ViewBag)114 {115 116 117 RefRequestEntity paras = SetParamValue(model);118 119 var t = HuberHttpModule.CurDomainAssembly.GetType(HuberHttpModule.CurDomainAssemblyName + ".Controllers." + controllerName + "Controller");120 var ActionFunc = t.GetMethod(partialViewName);121 object dObj = Activator.CreateInstance(t);122 123 var AddViewBageFunc = t.GetMethod("AddViewBageValues");124 125 foreach (string key in ViewBag.GetDynamicMemberNames())126 {127 128 AddViewBageFunc.Invoke(dObj, new object[] { key, Impromptu.InvokeGet(ViewBag, key) });129 }130 131 object result = ActionFunc.Invoke(dObj, new object[] { paras });132 return new RawString((result as RefRespondEntity).ResultContext.ToString());133 }134 135 }View Code
HuberReferenceResolver:我们定义的Razor中用的类库依赖。
1 public class HuberReferenceResolver : IReferenceResolver 2 { 3 4 static List<CompilerReference> compilerReference; 5 static HuberReferenceResolver() 6 { 7 //加载本地所有类库,@using 使用 8 compilerReference = new List<CompilerReference>(); 9 IEnumerable<string> loadedAssemblies = (new UseCurrentAssembliesReferenceResolver())10 .GetReferences(null, null)11 .Select(r => r.GetFile())12 .ToArray();13 foreach (var l in loadedAssemblies)14 {15 compilerReference.Add(CompilerReference.From(l));16 }17 18 19 20 }21 22 public string FindLoaded(IEnumerable<string> refs, string find)23 {24 return refs.First(r => r.EndsWith(System.IO.Path.DirectorySeparatorChar + find));25 }26 public IEnumerable<CompilerReference> GetReferences(TypeContext context, IEnumerable<CompilerReference> includeAssemblies)27 {28 29 #region 加载依赖程序集 此处是加载所有程序集,效率需要改进30 31 return compilerReference;32 #endregion33 }34 }View Code
CompileViewAndLayout()是编译视图文件的主要部分,其中有路径的转换、key的定义规则等。
获取视图文件对应编译后的缓存key: Engine.Razor.GetKey();
编译模板文件(即layout部分): Engine.Razor.AddTemplate();
编译视图文件: Engine.Razor.RunCompile()。
转载请注明出处:http://www.cnblogs.com/eric-z/p/5102718.html

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











공식 계정 웹 페이지 업데이트 캐시, 이것은 간단하고 간단하며 냄비를 마시기에 충분히 복잡합니다. 공식 계정 기사를 업데이트하기 위해 열심히 노력했지만 사용자는 여전히 기존 버전을 열었습니까? 이 기사에서는이 뒤에있는 비틀기와 회전을 살펴 보고이 문제를 우아하게 해결하는 방법을 살펴 보겠습니다. 읽은 후에는 다양한 캐싱 문제를 쉽게 처리 할 수있어 사용자가 항상 가장 신선한 콘텐츠를 경험할 수 있습니다. 기본 사항에 대해 먼저 이야기 해 봅시다. 액세스 속도를 향상시키기 위해 브라우저 또는 서버는 일부 정적 리소스 (예 : 그림, CSS, JS) 또는 페이지 컨텐츠를 저장합니다. 다음에 액세스 할 때 다시 다운로드하지 않고도 캐시에서 직접 검색 할 수 있으며 자연스럽게 빠릅니다. 그러나 이것은 또한 양날의 검입니다. 새 버전은 온라인입니다.

이 기사에서는 브라우저에서 직접 사용자 입력을 검증하기 위해 필요한, Pattern, Min, Max 및 Length 한계와 같은 HTML5 양식 검증 속성을 사용하는 것에 대해 설명합니다.

기사는 HTML5 크로스 브라우저 호환성을 보장하기위한 모범 사례에 대해 논의하고 기능 감지, 점진적 향상 및 테스트 방법에 중점을 둡니다.

이 기사는 CSS를 사용한 웹 페이지에 효율적인 PNG 테두리 추가를 보여줍니다. CSS는 JavaScript 또는 라이브러리에 비해 우수한 성능을 제공하며, 미묘하거나 눈에 띄는 효과를 위해 테두리 너비, 스타일 및 색상 조정 방법을 자세히 설명합니다.

이 기사는 HTML & LT; Datalist & GT에 대해 논의합니다. 자동 완성 제안을 제공하고, 사용자 경험을 향상시키고, 오류를 줄임으로써 양식을 향상시키는 요소. 문자 수 : 159

이 기사는 HTML & lt; meter & gt에 대해 설명합니다. 범위 내에 스칼라 또는 분수 값을 표시하는 데 사용되는 요소 및 웹 개발의 일반적인 응용 프로그램. & lt; meter & gt; & lt; Progress & Gt; 그리고 Ex

이 기사는 html5 & lt; time & gt; 시맨틱 날짜/시간 표현 요소. 인간이 읽을 수있는 텍스트와 함께 기계 가독성 (ISO 8601 형식)에 대한 DateTime 속성의 중요성을 강조하여 Accessibilit를 향상시킵니다.

이 기사는 HTML & lt; Progress & Gt에 대해 설명합니다. 요소, 그 목적, 스타일 및 & lt; meter & gt의 차이; 요소. 주요 초점은 & lt; progress & gt; 작업 완료 및 & lt; meter & gt; Stati의 경우
