65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET MVC 中视图引擎设置的性能改进和自定义视图引擎的实现

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.96/5 (6投票s)

2014年8月6日

CPOL

4分钟阅读

viewsIcon

27882

在本文中,我们将了解 ASP.NET MVC 应用程序中的自定义视图引擎和视图引擎设置。

引言

顾名思义,在本文中,我们将通过附加正确的视图引擎来了解 MVC 中的一些性能改进,然后我们将学习扩展现有的 Razor 视图引擎和实现我们自己的视图引擎。所以,让我们先从视图引擎调优部分开始。我们知道 ActionResult 是所有操作结果类型的父类,而 ViewResult 是其中之一。如果我们想返回一个 View,我们可以显式指定视图名称,也可以不指定。现在,视图执行过程由视图引擎处理,它在 MVC 管道的最后部分执行。首先,它决定返回结果是否为 ViewResult 类型,如果结果是 ViewResult 类型,则由视图引擎负责调用适当的视图。通常,MVC 框架默认使用两个视图引擎,分别是 Web Form 视图引擎和 Razor 视图引擎,MVC 框架首先搜索 Web Form 视图引擎,如果不存在,则搜索 Razor 视图引擎。所以,理论上,每当 MVC 框架想要调用一个视图时,它会先搜索 Web Form 视图引擎,然后搜索 Razor 视图引擎,即使我们在应用程序中只使用 Razor 视图引擎。所以,让我们实际看一下。这是包含 Index() 操作的控制器,我们正尝试返回应用程序中不存在的 Test 视图。

      public class TestController : Controller
      {
        public ActionResult Index()
        {
            return View("Test");
        }
    }

显然,我们应该看到下面的屏幕,因为我们根本没有这个视图。如果我们仔细检查搜索步骤,我们会看到 MVC 框架首先搜索 .aspx 页面,然后搜索 .cshtml 等等,所以 Web Form 视图首先执行,然后是 Razor 视图。

正如我们之前所说,这会减慢视图执行过程,好的。让我们来解决这个问题。我们知道 MVC 是高度可定制和可配置的。现在,我们将从 MVC 管道中分离 Web Form 视图引擎,只附加 Razor 视图引擎,这样框架在执行时就不会搜索 Web Form 视图。这个过程非常简单。只需打开应用程序的 Global.asax 文件并相应地修改代码。

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            //Remove all view engine
            ViewEngines.Engines.Clear();

            //Add Razor view Engine
            ViewEngines.Engines.Add(new RazorViewEngine());

            Bootstrapper.Initialise();
        }
    }

在这里,我们清除了 MVC 管道中的所有视图引擎,然后只注册了 Razor 视图引擎。现在,如果我们运行相同的应用程序,我们将看到下面的输出,并且我们看到 MVC 框架现在不再搜索 .aspx 页面。

自定义 Razor 视图引擎

现在,应用程序中还有另一个小问题。我们看到 Razor 视图引擎同时搜索 vbhtml 和 cshtml 页面。现在,在应用程序中,你可能只在视图中使用一种编程语言,C# 或 VB,这是非常常见的。所以,这里我们可以再次自定义现有的 Razor 视图引擎,让它只搜索 cshtml 页面或 vbhtml 页面。所以,只需创建一个类并继承自 RazorViewEngine 类。下面是一个示例实现

public class CSharpRazorViewEngine : RazorViewEngine
    {
        public CSharpRazorViewEngine()
        {
            AreaViewLocationFormats = new[]
             {
             "~/Areas/{2}/Views/{1}/{0}.cshtml",
             "~/Areas/{2}/Views/Shared/{0}.cshtml"
             };
                        AreaMasterLocationFormats = new[]
             {
             "~/Areas/{2}/Views/{1}/{0}.cshtml",
             "~/Areas/{2}/Views/Shared/{0}.cshtml"
             };
                        AreaPartialViewLocationFormats = new[]
             {
             "~/Areas/{2}/Views/{1}/{0}.cshtml",
             "~/Areas/{2}/Views/Shared/{0}.cshtml"
             };
                        ViewLocationFormats = new[]
             {
             "~/Views/{1}/{0}.cshtml",
             "~/Views/Shared/{0}.cshtml"
             };
                        MasterLocationFormats = new[]
             {
             "~/Views/{1}/{0}.cshtml",
             "~/Views/Shared/{0}.cshtml"
             };
                        PartialViewLocationFormats = new[]
             {
             "~/Views/{1}/{0}.cshtml",
             "~/Views/Shared/{0}.cshtml"
             };
        }
    }

现在,我们必须在 MVC 管道中注册视图引擎。只需相应地修改 Global.asax 文件。

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            //Remove all view engine
            ViewEngines.Engines.Clear();

            //Add Custom view Engine Derived from Razor
            ViewEngines.Engines.Add(new CSharpRazorViewEngine());

            Bootstrapper.Initialise();
        }
    }

现在,如果我们运行应用程序,我们将看到自定义视图引擎只搜索 .cshtml 页面。

好的,我们已经学会了如何自定义视图引擎以提高 MVC 应用程序的性能。现在,我们将构建自己的视图引擎,并将该引擎替换现有的 Web Form 视图或 Razor 视图。

实现自定义视图引擎

要实现我们自己的视图引擎,我们必须在我们自己的类中实现 IViewEngine IViewEngine 包含三个方法。

  • FindPartialView:如果主视图中有任何部分视图调用,此方法将搜索部分视图。
  • FindView:此方法将搜索主视图。
  • ReleaseView:视图执行后,我们可以实现自定义视图类的处置活动。

在这里,我在“MyViewEngine”类中实现了 IViewEngine 接口。看一下下面的代码

 public class MyViewEngine : IViewEngine 
    {
        public ViewEngineResult FindPartialView
        (ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            throw new NotImplementedException();
        }

        public ViewEngineResult FindView(ControllerContext controllerContext,
            string viewName, string masterName, bool useCache)
        {
            if (viewName.Contains("myView")) 
            {
                return new ViewEngineResult(new myCustomView(),this);
            }
            else
                return new ViewEngineResult(new string[] {"No View found, please provide correct name"});
        }

        public void ReleaseView(ControllerContext controllerContext, IView view)
        {
            
        }
    }

所以,我们已经构建了自己的视图引擎,现在我们必须构建自己的视图。要构建我们自己的视图,我们必须在我们自己的类中实现 IView 接口。在本例中,我在 myCustomView 类中实现了 IView 接口。IView 只包含一个名为 Render 的方法,我们可以在其中实现渲染机制。在本例中,我们只是打印 string

  public class myCustomView : IView
    {
        public void Render(ViewContext viewContext, System.IO.TextWriter writer)
        {
            writer.Write("Data from custom view");
        }
    }

注册自定义视图

这是我们需要遵循的一个明显过程。我们必须在 MVC 管道中注册自定义视图。只需相应地修改 Global.asax 页面。

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            //Remove all view engine
            ViewEngines.Engines.Clear();

            //Attach custom view in pipeline
            ViewEngines.Engines.Add(new MyViewEngine());
                        
            Bootstrapper.Initialise();
        }

现在,我们将实现控制器,然后调用我们的自定义视图。这里我将操作名称指定为 myView

public class TestController : Controller
    {
        public ActionResult myView()
        {
            return View();
        }
    }

一旦我们运行应用程序并尝试命中 myView() 操作,我们将看到自定义的 string 已出现在屏幕上。

总结

在本例中,我们学习了如何在 MVC 应用程序中配置视图引擎,也学习了如何实现自定义视图引擎。希望本文能让你更好地理解 MVC 应用程序中的视图执行过程。

© . All rights reserved.