创建一个自定义View Engine
让我们从创建一个自定义的View Engine开始。Listing 1中包含了一个叫做SimpleViewEngine的非常简单的View Engine。
Listing 1 – SimpleViewEngine.cs (C#)
namespace Tip25 { public class SimpleViewEngine : IViewEngine { private string _viewsFolder = null; public SimpleViewEngine() { if (HttpContext.Current != null) { var root = HttpContext.Current.Request.PhysicalApplicationPath; _viewsFolder = Path.Combine(root, "Views"); } } public SimpleViewEngine(string viewsFolderPhysicalPath) { _viewsFolder = viewsFolderPhysicalPath; } public void RenderView(ViewContext viewContext) { if (_viewsFolder == null) throw new NullReferenceException("You must supply a viewsFolder path"); string fullPath = Path.Combine(_viewsFolder, viewContext.ViewName) + ".htm"; if (!File.Exists(fullPath)) throw new HttpException(404, "Page Not Found"); // Load file string rawContents = File.ReadAllText(fullPath); // Perform replacements string parsedContents = Parse(rawContents, viewContext.ViewData); // Write results to HttpContext viewContext.HttpContext.Response.Write(parsedContents); } public string Parse(string contents, ViewDataDictionary viewData) { return Regex.Replace(contents, @"\{(.+)\}", m => GetMatch(m, viewData)); } protected virtual string GetMatch(Match m, ViewDataDictionary viewData) { if (m.Success) { string key = m.Result("$1"); if (viewData.ContainsKey(key)) return viewData[key].ToString(); } return String.Empty; } } } |
注意SimpleViewEngine 实现了IViewEngine 接口。该接口有一个RenderView()方法必须实现。
在Listing 1中,RenderView()方法从硬盘中加载一个文件,并用ViewData中的项目来替换文件中的标签(tokens)。在Listing 2中,包含了一个使用SimpleViewEngine的 controller 。当你调用HomeController.Index() action时,它返回一个叫做Index的 view。
Listing 2 – HomeController.cs (C#)
namespace Tip25.Controllers { [HandleError] public class HomeController : Controller { public HomeController() { this.ViewEngine = new SimpleViewEngine(); } public ActionResult Index() { ViewData["Message"] = "Welcome to ASP.NET MVC!"; ViewData["Message2"] = "Using a custom View Engine"; return View("Index"); } } } |