天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

NVelocity for ASP.NET MVC

  在我的這篇博文中,有這么一段話:“我一直在想,有沒有辦法可以單獨限制View中的代碼的訪問權限,類似于trust level,只是這個trust level是用來限制模板中的代碼。”。有讀者johngeng問,為什么要用trust level來鎖住view,他不是很理解。我的本意是,希望在view中,開發人員只能寫某一些特定功能的代碼,調用某一些特定開放的API,對于大部分安全級比較高的代碼,比如讀寫文件等API或類庫,不允許在view當中使用。這對于我們將模板開放出來,在線提供給我們的用戶去修改的需求下是非常重要的。而目前,不管WebForm還是Razor,都是非常自由的模板,在View能做的事情等同于Controller或其它地方所寫的代碼,這樣View就不允許開放出來由用戶在線修改。

  在相同的博文里面,還是那位讀者johngeng提到它更喜歡$而不是@,由于我之前并不了解NVelocity,所以我誤解為它是在說客戶端開發包jquery。現在看來,他說的應該就是NVelocity,也許他覺得此人不可教,他并沒有直接回復我的疑問,這也只能怪自己知識面太窄了。

  若不是最近在為項目添加多模板引擎的支持,或許我永遠也無法得到以上兩個問題的答案,而這兩個答案都與NVelocity有關。雖然我平常肯定也見過NVelocity這個詞,但到要選擇除WebForm以外的模板引擎,我還是完完全全沒有記起他,還是同事@浪子提醒我NVelocity這個模板引擎值得一試。看了官方的語法介紹后,我不得不說它是一種非常簡潔且實用的模板,同時又不失它的靈活性和安全性。我所指的靈活性是它不像StringTemplate那樣,限制的那么死,連個對象的函數都不允許調用。安全性方面又可以滿足我希望模板上限制開發人員只能在模板上調用指定的API。到目前為止,NVelocity仍然讓我非常滿意。

  在ASP.NET MVC切換視圖引擎非常簡單,在ASP.NET MVC1.0出來以后,MvcContrib就曾經提供了多種視圖引擎的切換選擇,但是在最近的版本中,我卻始終沒有找到相關的代碼,應該是這些代碼已經被移出去了,但它的介紹文檔中還沒有刪掉相關的主題。還好在@重典童鞋的博客上找到了他從MvcContrib中提取出來的實現。但是這個實現相對于MVC3來說,已經相對過時了,有些接口已經改變或被移除了,比如IViewLocator這個接口就已經不存在了。還有就是,它去掉了原先支持的調用HtmlHelper擴展方法的功能,而我最重要的就是要支持擴展函數,因為我自定義了一些必須的擴展方法。下面我們就來看看NVelocity for ASP.NET MVC幾個類的詳細情況:

  NVelocityViewEngine

  在之前的實現中,直接實現了IViewEngine這個接口,查找View的路徑是通過實現IViewLocator來定位。在MVC2當中,修改了這部分的實現,MVC內部提供了VirtualPathProviderViewEngine這個模板方法類,在子類當中,我們中需要設置一下我們要查找的路徑格式,其它的事件就可以交給模板方法類來完成,這樣一方面可以簡化我們的實現,另一方面還可以和默認的路徑查找方式統一。

  同時,由于我使用Nvelocity內置的相對文件路徑的方式來查找模板,而使用VirtualPath的風格,因此在找到VirtualPath后,我們需要轉換成實際的物理路徑,直接通過物理路徑來加載模板內容,而內置的FileResourceLoader并不支持從物理路徑加載模板,所以我們還要額外實現一下FileResourceLoader,讓支持從物理路徑的加載方法。這兩個類的代碼如下:

public class FileResourceLoaderEx : FileResourceLoader
{
public FileResourceLoaderEx() : base() { }
private Stream FindTemplate(string filePath)
{
try
{
FileInfo file
= new FileInfo(filePath);
return new BufferedStream(file.OpenRead());
}
catch (Exception exception)
{
base.runtimeServices.Debug(string.Format("FileResourceLoader : {0}", exception.Message));
return null;
}
}
public override long GetLastModified(global::NVelocity.Runtime.Resource.Resource resource)
{
if (File.Exists(resource.Name))
{
FileInfo file
= new FileInfo(resource.Name);
return file.LastWriteTime.Ticks;
}
return base.GetLastModified(resource);
}
public override Stream GetResourceStream(string templateName)
{
if (File.Exists(templateName))
{
return FindTemplate(templateName);
}
return base.GetResourceStream(templateName);
}
public override bool IsSourceModified(global::NVelocity.Runtime.Resource.Resource resource)
{
if (File.Exists(resource.Name))
{
FileInfo file
= new FileInfo(resource.Name);
return (!file.Exists || (file.LastWriteTime.Ticks != resource.LastModified));
}
return base.IsSourceModified(resource);
}
}
public class NVelocityViewEngine : VirtualPathProviderViewEngine, IViewEngine
{
public static NVelocityViewEngine Default = null;

private static readonly IDictionary DEFAULT_PROPERTIES = new Hashtable();
private readonly VelocityEngine _engine;

static NVelocityViewEngine()
{
string targetViewFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "views");
//DEFAULT_PROPERTIES.Add(RuntimeConstants.RESOURCE_LOADER, "file");
DEFAULT_PROPERTIES.Add(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, targetViewFolder);
DEFAULT_PROPERTIES.Add(
"file.resource.loader.class", "NVelocityEngine.FileResourceLoaderEx//,NVelocityEngine");
Default
= new NVelocityViewEngine();
}
public NVelocityViewEngine()
:
this(DEFAULT_PROPERTIES)
{
}
public NVelocityViewEngine(IDictionary properties)
{
base.MasterLocationFormats = new string[] { "~/Views/{1}/{0}.vm", "~/Views/Shared/{0}.vm" };
base.AreaMasterLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}.vm", "~/Areas/{2}/Views/Shared/{0}.vm" };
base.ViewLocationFormats = new string[] { "~/Views/{1}/{0}.vm", "~/Views/Shared/{0}.vm" };
base.AreaViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}.vm", "~/Areas/{2}/Views/Shared/{0}.vm" };
base.PartialViewLocationFormats = base.ViewLocationFormats;
base.AreaPartialViewLocationFormats = base.AreaViewLocationFormats;
base.FileExtensions = new string[] { "vm" };
if (properties == null) properties = DEFAULT_PROPERTIES;

ExtendedProperties props
= new ExtendedProperties();
foreach (string key in properties.Keys)
{
props.AddProperty(key, properties[key]);
}

_engine
= new VelocityEngine();
_engine.Init(props);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
Template viewTemplate
= GetTemplate(viewPath);
Template masterTemplate
= GetTemplate(masterPath);
NVelocityView view
= new NVelocityView(controllerContext, viewTemplate, masterTemplate);
return view;
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
Template viewTemplate
= GetTemplate(partialPath);
NVelocityView view
= new NVelocityView(controllerContext, viewTemplate, null);
return view;
}
public Template GetTemplate(string viewPath)
{
if (string.IsNullOrEmpty(viewPath))
{
return null;
}
return _engine.GetTemplate(System.Web.Hosting.HostingEnvironment.MapPath(viewPath));
}
}

NET技術NVelocity for ASP.NET MVC,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 日日噜噜夜夜狠狠扒开双腿 | 午夜影院一区二区三区 | 天美传媒果冻传媒入口视频 | 欧美男男网站免费观看videos | 国产亚洲福利在线视频 | 青柠在线观看视频在线高清 | 少妇被阴内射XXXB少妇BB | yellow日本动漫观看免费 | 亚洲国产精品高清在线 | 日韩免费一区二区三区在线 | 在线观看永久免费网址 | 中文字幕亚洲第一 | 日韩精品免费在线观看 | 国产免费内射又粗又爽密桃视频 | 亚洲蜜桃AV色情精品成人 | 伦理79电影网在线观看 | 麻豆精品一区二正一三区 | 秋霞电影网午夜鲁丝片 | a级老头和老太xxxx | 男人吃奶摸下挵进去啪啪 | 婷婷久久无码欧美人妻 | 四虎影院2022 | 大陆女人内谢69XXXORG | 伊人国产在线视频 | 久久国产欧美日韩精品免费 | jizzxxxx18中国内地 | 国产午夜亚洲精品一区 | 大胸美女被C得嗷嗷叫动态图 | 父亲在线日本综艺免费观看全集 | 欧美高清18 | 久久伊人男人的天堂网站 | 亚洲中文无码AV在线观看 | YELLOW视频直播在线观看高清 | 男人被绑着强行摸j | 午夜免费福利 | 9420高清免费观看在线大全 | 伊人久久大香线蕉综合网站 | 国产偷啪自怕网 | 乐乐亚洲精品综合影院 | 亚洲综合AV在线在线播放 | 91精品免费久久久久久久久 |