天天看點

(翻譯)為你的MVC應用程式建立自定義視圖引擎

Creating your own MVC View Engine For MVC Application

原文連結:http://www.codeproject.com/Articles/294297/Creating-your-own-MVC-View-Engine-into-MVC-Applica

簡介(Introduction):

The View engines used in ASP.NET MVC Framework are the Razor View Engine and Web Form View Engine. Razor View engine used .cshtml and .vbhtml. While Web Form View Engine used .aspx to design the layout of the user interface.

微軟的ASP.NET MVC架構中使用的視圖引擎一般有二:Razor和Web Form視圖引擎。對于Razor來說,其使用的頁面檔案以.cshtml或者.vbhtml作為字尾。而Web Form 視圖引擎則以aspx檔案作為界面呈現。

The ASP.NET MVC Framework was designed to support alternative view engines and there are already several open source alternatives to the web forms view engine like Nhaml (pronounced enamel), spark, Brail, nVelocity. The different View Engines enable to write your view in different ways.

另一方面,ASP.NET MVC架構同樣支援自定義視圖引擎。到目前為止,已經有若幹開源的Web Form視圖引擎可供選擇,比如Nhaml(全稱為:pronounced enamel)、spark, Brail, nVelocity等。不同的視圖引擎可以讓你以不同的方式編寫你的使用者界面。

It is possible to use multiple view engines used in one MVC application. For that, it is required to registering multiple engines in the global.aspx file.

在微軟的MVC項目中,支援同時使用多個視圖引擎用于頁面渲染。為了做到這一點,隻需要在global.aspx注冊這些引擎即可。

自定義視圖引擎(Custom View Engines):

It is very simple to create your own custom view engine. When you create your own view engine, you have to just think about how you want to write your views.

建立屬于你的視圖引擎非常簡單。在這之前,你需要确定的問題是以何種方式編寫你的視圖檔案。

The easiest approach to create custom view engine is just derive a new view engine from abstract VirtualPathProviderViewEngine Class. This base class can take care of the all low-level mechanics of finding and caching views.

自定義視圖引擎最簡單的方式就是繼承VirtualPathProviderViewEngine抽象類并實作必需的方法。VirtualPathProviderViewEngine類已經幫你實作了定位及緩存視圖檔案的功能。(譯者注:VirtualPathProviderViewEngine 抽象類實作了IViewEngine接口。直接實作IViewEngine接口則需要覆寫FindView 及 FindPartialView等方法)

Now take a simple example of MyViewEngine it will return simple view.

下面讓我們以一個簡單的MyViewEngine來進行說明。最終該視圖引擎會渲染一個簡單的視圖檔案。

The first step is to create an empty MVC application. Then add a class file named MyViewEngine.cs and inherit that class from VirtualPathProviderViewEngine and override createview and createpartialview methods. These methods return an instance of the MYView Class. Your class will look like below:

首先我們建立一個空的MVC項目,然後添加一個 MyViewEngine.cs 類檔案并讓其繼承自 VirtualPathProviderViewEngine抽象類。覆寫createview 和 createpartialview 方法。二者均傳回一個MyView的執行個體。代碼如下:

public class MyViewEngine : VirtualPathProviderViewEngine
    {
        public MyViewEngine()
        {
            // Define the location of the View file
            this.ViewLocationFormats = new string[] 
        { "~/Views/{1}/{0}.myview", "~/Views/Shared/{0}.myview" };

            this.PartialViewLocationFormats = new string[] 
        { "~/Views/{1}/{0}.myview", "~/Views/Shared/{0}.myview" };
        }

        protected override IView CreatePartialView
    (ControllerContext controllerContext, string partialPath)
        {
            var physicalpath = controllerContext.HttpContext.Server.MapPath(partialPath);
            return new MyView(physicalpath);
        }

        protected override IView CreateView
    (ControllerContext controllerContext, string viewPath, string masterPath)
        {
            var physicalpath = controllerContext.HttpContext.Server.MapPath(viewPath);
            return new MyView(physicalpath);
        }
    }      

Note that in the constructor, we set two properties of the base class. These properties indicate where the view engine should search to find a matching view or partial view.The parameter {1} represents the name of the controller and the parameter {0} represents the name of the action.

注意在構造函數中,我們設定了抽象基類的兩個屬性。這兩個屬性辨別了視圖引擎到何處去比對我們的View和PartialView。其中,第一個參數代表了controller,第二個參數則代表action。

Now, create another class named MyView which implements IView interface. This class actually renders the view. MyView class code looks like below:

接下來建立MyView類,使其繼承自IView接口。真正的渲染視圖檔案的工作将在該類中完成。其完整代碼如下:

public class MyView : IView
    {
        private string _viewPhysicalPath;

        public MyView(string ViewPhysicalPath)
        {
            _viewPhysicalPath = ViewPhysicalPath;
        }

        #region IView Members

        public void Render(ViewContext viewContext, System.IO.TextWriter writer)
        {
            //Load File
            string rawcontents = File.ReadAllText(_viewPhysicalPath);

            //Perform Replacements
            string parsedcontents = Parse(rawcontents, viewContext.ViewData);

            writer.Write(parsedcontents);
        }

        #endregion

        public string Parse(string contents, ViewDataDictionary viewdata)
        {
            return Regex.Replace(contents, "\\{(.+)\\}", m => GetMatch(m,viewdata));
        }

        public 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;
        }
    }      

Render method of the class loads the view files and injects view data into the view, and writes that result into a text writer.

MyView類中的Render方法首先加載視圖檔案,然後結合相關資料進行解析。最後将解析後的結果輸出至文本流。

Before use, custom view engine is required to register view engine into Global.asax file using the following code:

在實際使用自定義視圖引擎之前,需要我們用以下代碼在Global.asax檔案中進行注冊:

protected void Application_Start()
 {
       AreaRegistration.RegisterAllAreas();

       RegisterGlobalFilters(GlobalFilters.Filters);
       RegisterRoutes(RouteTable.Routes);

       //Register your View Engine Here.
       ViewEngines.Engines.Add(new MyViewEngine());
}      

Now create a controller file into controller folder named myViewController and define index action into the controller. Your controller class will look like below:

現在我們在Controller目錄下建立一個名為MyViewController的控制器,在該controller中定義一個action:Index。代碼如下:

public class MyViewController : Controller
 {
      //
     // GET: /myView/
     public ActionResult Index()
     {
         ViewData["Message"] = "Hello World!";
         return View();
     }
}      

Now add the simple HTML File into View/MyView/ folder and give the name of the file like index.myview. Your view file markup looks like below:

接下來在 View/MyView/ 目錄下,建立一個簡單的HTML檔案,修改名稱為Index.myview,其最終代碼如下:

<html>
<head>
             <title>Index MyView </title>
</head>
<body>{message}
</body>
</html>       

Now run the application and type URL /MyView /Index. You will get output of the Hello World! into the browser. The MyView class loads the index.myview file and replaces {message} with hello world! and renders the HTML Page.

現在運作你的應用程式,修改位址欄中URL為:/MyView/Index,你将會在浏覽器中看到"Hello World!"的輸出。也就是說,MyView類加載了Index.myview檔案,替換其中的{message}标簽為"Hello World!",将其渲染成為Html頁面。

結論(Conclusion):

After developing Custom View Engine, we can say that MVC team has done an awesome job at providing a very flexible framework for us to tweak and customize it so it fits our applications.

從上述自定義視圖引擎的過程可以看出:MVC開發團隊做了大量牛逼的工作,提供了一個高度靈活、高度可擴充的開發架構,以适應不同場景下的應用程式開發。

版權(License):

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

本文及其附帶的源代碼檔案,均遵從CPOL開源協定。