Click here to Skip to main content
Click here to Skip to main content

Custom ViewEngine in ASP.NET MVC3

, 24 Sep 2011
Rate this:
Please Sign up or sign in to vote.
MVC is a standard design pattern that many developers are familiar with. Some types of Web applications will benefit from the MVC framework.
Custom View Engine Output

Output Image

About MVC3 in ASP.NET

The Model-View-Controller (MVC) architectural pattern separates an application into three main components: the Model, the View, and the Controller. The ASP.NET MVC framework provides an alternative to the ASP.NET Web Forms pattern for creating Web applications. The ASP.NET MVC framework is a lightweight, highly testable presentation framework that (as with Web Forms-based applications) is integrated with existing ASP.NET features, such as master pages and membership-based authentication. The MVC framework is defined in the System.Web.Mvc assembly. More...

The MVC separates the user interface of an application into three main aspects:

  • The Model: A set of classes that describes the data you are working with as well as the business rules for how the data can be changed and manipulated.
  • The View: Defines how the application’s user interface (UI) will be displayed.
  • The Controller: A set of classes that handles communication from the user, overall application flow, and application-specific logic.

View Engine

By default, two View Engines RazorViewEngine and WebFormViewEngine are available in MVC3. But if we want to create a custom View Engine, we can use the IViewEngine interface.

IViewEngine has three methods: FindView, FindPartialView, ReleaseView. Note that the FindPartialView method works in the same way as FindView, except that it focuses on finding a partial view. The IViewEngine interface structure looks like:

public interface IViewEngine 
{
   ViewEngineResult FindPartialView(ControllerContext controllerContext, 
                    string partialViewName, bool useCache);
   ViewEngineResult FindView(ControllerContext controllerContext, 
                    string viewName,string masterName, bool useCache);
   void ReleaseView(ControllerContext controllerContext, IView view);
}

The IView interface is the second interface we need to implement when implementing a custom View Engine. The IView interface structure is:

public interface IView 
{
  void Render(ViewContext viewContext, TextWriter writer);
}

Custom Views have a ViewContext instance and a TextWriter instance to provide the information required for a custom View Engine, along with a TextWriter instance. The View is expected to consume the data in the ViewContext (such as the View data and Model) and then call methods of the TextWriter instance to render the output.

Creating a Custom View Engine

  1. Create an empty project of type MVC3 Application.
  2. Create a class Person in the Model directory.
  3. public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
  4. Create a folder Infrastructure/CustomViewEngine in the Views directory.
  5. Create a class MyView in the Infrastructure/CustomViewEngine folder and derived from the interface IVew.
  6. public class MyView : IView
     {
        public void Render(ViewContext viewContext, TextWriter textWriter)
        {
            Write(textWriter, "<u>Route Information</u>");
            foreach (string sKey in viewContext.RouteData.Values.Keys)
            { Write(textWriter, "<br/><b>Key</b>: {0}, <b>Value</b>: {1}", 
                      sKey, viewContext.RouteData.Values[sKey]); }
            Write(textWriter, "<br/><u>View Information</u>");
            foreach (string sKey in viewContext.ViewData.Keys)
            { Write(textWriter, "</br><b>Key</b>: {0}, <b>Value</b>: {1}", 
              sKey, viewContext.ViewData[sKey]); }
            Write(textWriter, "<br/><u>Model Information</u></br>");
            var pList = viewContext.ViewData.Model as List<Person>;
            Write(textWriter, "<table width='200px'><tr><th " + 
                  "align='left'>Id</th><th align='left'>Name</th></tr>");
            foreach (Person p in pList)
            { Write(textWriter, "<tr><td>{0}</td><td>{1}</td></tr>", p.Id, p.Name); }
            Write(textWriter, "</table>");
        }
        private void Write(TextWriter textWriter, string sTemplate, 
                           params object[] oValues)
        {
          textWriter.Write(string.Format(sTemplate, oValues));
        }
    }
  7. Then create a class MyViewEngine in the Infrastructure/CustomViewEngine folder and derived from the interface IVewEngine.
  8. public class MyViewEngine:IViewEngine
    {
        public ViewEngineResult FindView(ControllerContext controllerContext, 
               string viewName,string masterName,bool useCache)
        {
            if (viewName == "MyView")
            { return new ViewEngineResult(new MyView(), this); }
            else
            { return new ViewEngineResult(new string[]{"My dataview engine"}); }
        }
        public ViewEngineResult FindPartialView(ControllerContext controllerContext, 
               string partialViewName, bool useCache)
        {
            if (partialViewName == "MyView")
            { return new ViewEngineResult(new MyView(), this); }
            else
            { return new ViewEngineResult(new string[] { "My dataview engine" }); }
        }
        public void ReleaseView(ControllerContext controllerContext, IView iView)
        { }
    }

    Here we are using the same view MyView in both methods FindView and FindPartialView, only for using the Index method of HomeController to check both Views by using return View() and return PartialView() and passing a View name.

  9. Then create a controller Home and write code in the Index() method of HomeController.
  10. public ActionResult Index()
    {
        ViewData["Messgae"] = "My Custom View Engine";
        ViewData["Time"] = DateTime.Now.ToShortDateString();
        List<Person> pList = new List<Person>{
            new Person{Id=1,Name="rajesh"},
            new Person{Id=2,Name="prakash"},
            new Person{Id=3,Name="manish"}
        };
        ViewData.Model = pList;
        return View("MyView");
    }
  11. Open Global.asax.cs and add your custom View Engine. If you debug the application, by default two View Engines RazorViewEngine and WebFormViewEngine are available and both are registered.
  12. You need to call the Clear method first because RazorViewEngine and WebFormViewEngine are included in that collection by default. Calling the Clear method is not necessary if you want to add your custom View Engine as another option in addition to the default one, rather than replace the default View Engines.

    protected void Application_Start()
    {
       ViewEngines.Engines.Clear();
       ViewEngines.Engines.Add(new MyViewEngine());
       RegisterRoutes(RouteTable.Routes);
    }
  13. Build and run the application.

Replace return View("MyView") with return PartialView("MyView") for PartialView.

License

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

About the Author

R S Dodiya
Software Developer (Senior)
India India

Comments and Discussions

 
GeneralMy vote of 2 Pinmembereclipse2k114-Oct-13 22:56 
QuestionWhy do we even need IViewEngine? PinmemberclintonG26-Sep-11 9:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 24 Sep 2011
Article Copyright 2011 by R S Dodiya
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid