웹 프론트엔드 HTML 튜토리얼 第四篇 基于.net搭建热插拔式web框架(RazorEngine实现)_html/css_WEB-ITnose

第四篇 基于.net搭建热插拔式web框架(RazorEngine实现)_html/css_WEB-ITnose

Jun 24, 2016 am 11:30 AM

在开头也是先给大家道个歉,由于最近准备婚事导致这篇文章耽误了许久,同时也谢谢老婆大人对我的支持。

回顾上篇文章,我们重造了一个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
로그인 후 복사
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

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

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

공식 계정 웹 페이지의 캐싱 업데이트에 어려움 : 버전 업데이트 후 사용자 경험에 영향을 미치는 이전 캐시를 피하는 방법은 무엇입니까? 공식 계정 웹 페이지의 캐싱 업데이트에 어려움 : 버전 업데이트 후 사용자 경험에 영향을 미치는 이전 캐시를 피하는 방법은 무엇입니까? Mar 04, 2025 pm 12:32 PM

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

HTML5 양식 유효성 검사 속성을 사용하여 사용자 입력을 유효성있게하려면 어떻게합니까? HTML5 양식 유효성 검사 속성을 사용하여 사용자 입력을 유효성있게하려면 어떻게합니까? Mar 17, 2025 pm 12:27 PM

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

HTML5의 크로스 브라우저 호환성에 대한 모범 사례는 무엇입니까? HTML5의 크로스 브라우저 호환성에 대한 모범 사례는 무엇입니까? Mar 17, 2025 pm 12:20 PM

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

웹 페이지의 PNG 이미지에 뇌졸중 효과를 효율적으로 추가하는 방법은 무엇입니까? 웹 페이지의 PNG 이미지에 뇌졸중 효과를 효율적으로 추가하는 방법은 무엇입니까? Mar 04, 2025 pm 02:39 PM

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

& lt; datalist & gt의 목적은 무엇입니까? 요소? & lt; datalist & gt의 목적은 무엇입니까? 요소? Mar 21, 2025 pm 12:33 PM

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

& lt; meter & gt의 목적은 무엇입니까? 요소? & lt; meter & gt의 목적은 무엇입니까? 요소? Mar 21, 2025 pm 12:35 PM

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

html5 & lt; time & gt; 의미 적으로 날짜와 시간을 나타내는 요소? html5 & lt; time & gt; 의미 적으로 날짜와 시간을 나타내는 요소? Mar 12, 2025 pm 04:05 PM

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

& lt; Progress & Gt의 목적은 무엇입니까? 요소? & lt; Progress & Gt의 목적은 무엇입니까? 요소? Mar 21, 2025 pm 12:34 PM

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

See all articles