ホームページ ウェブフロントエンド htmlチュートリアル 記事 4: .net に基づくホットスワップ可能な Web フレームワークの構築 (RazorEngine によって実装)_html/css_WEB-ITnose

記事 4: .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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

公式アカウントのキャッシュの更新の難しさ:バージョンの更新後のユーザーエクスペリエンスに影響を与える古いキャッシュを回避する方法は? 公式アカウントのキャッシュの更新の難しさ:バージョンの更新後のユーザーエクスペリエンスに影響を与える古いキャッシュを回避する方法は? Mar 04, 2025 pm 12:32 PM

公式アカウントのWebページはキャッシュを更新します。これはシンプルでシンプルで、ポットを飲むのに十分な複雑です。あなたは公式のアカウントの記事を更新するために一生懸命働きましたが、ユーザーはまだ古いバージョンを開くことができますか?この記事では、この背後にあるtwist余曲折と、この問題を優雅に解決する方法を見てみましょう。それを読んだ後、さまざまなキャッシュの問題に簡単に対処でき、ユーザーが常に新鮮なコンテンツを体験できるようになります。最初に基本について話しましょう。それを率直に言うと、アクセス速度を向上させるために、ブラウザまたはサーバーはいくつかの静的リソース(写真、CSS、JSなど)やページコンテンツを保存します。次回アクセスするときは、もう一度ダウンロードすることなく、キャッシュから直接検索できます。自然に高速です。しかし、このことは両刃の剣でもあります。新しいバージョンはオンラインです、

HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? Mar 17, 2025 pm 12:27 PM

この記事では、ブラウザのユーザー入力を直接検証するために、必要、パターン、MIN、MAX、および長さの制限などのHTML5フォーム検証属性を使用して説明します。

HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? Mar 17, 2025 pm 12:20 PM

記事では、HTML5クロスブラウザーの互換性を確保するためのベストプラクティスについて説明し、機能検出、プログレッシブエンハンスメント、およびテスト方法に焦点を当てています。

WebページのPNG画像にストローク効果を効率的に追加する方法は? WebページのPNG画像にストローク効果を効率的に追加する方法は? Mar 04, 2025 pm 02:39 PM

この記事では、CSSを使用したWebページへの効率的なPNG境界追加を示しています。 CSSはJavaScriptやライブラリと比較して優れたパフォーマンスを提供し、微妙または顕著な効果のために境界幅、スタイル、色を調整する方法を詳述していると主張しています

&lt; datalist&gt;の目的は何ですか 要素? &lt; datalist&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:33 PM

この記事では、HTML&lt; Datalist&GT;について説明します。オートコンプリートの提案を提供し、ユーザーエクスペリエンスの改善、エラーの削減によりフォームを強化する要素。

&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の場合

HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? Mar 12, 2025 pm 04:05 PM

この記事では、html5&lt; time&gt;について説明します。セマンティックデート/時刻表現の要素。 人間の読み取り可能なテキストとともに、マシンの読みやすさ(ISO 8601形式)のDateTime属性の重要性を強調し、Accessibilitを増やします

&lt; meter&gt;の目的は何ですか 要素? &lt; meter&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:35 PM

この記事では、html&lt; meter&gt;について説明します。要素は、範囲内でスカラーまたは分数値を表示するために使用され、Web開発におけるその一般的なアプリケーション。それは差別化&lt; Meter&gt; &lt; Progress&gt;およびex

See all articles