How to create custom ViewEngine in MVC 2

As is we know, by default, the ViewEngine of MVC  is WebFormsViewEngine. After refector the source code, I find that the engine implement IView and VirtualPathProviderViewEngine. So we also can create custom engine.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.Linq;
namespace MvcApplication1.Models
{
    public class XSLTViewEngine:VirtualPathProviderViewEngine
    {
        public XSLTViewEngine() {
            ViewLocationFormats = PartialViewLocationFormats = new[] { 
               "~/Views/{1}/{0}.xslt","~/Views/Shared/{0}.xslt"
            };
        }
        protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
        {
            return new XSLTView(controllerContext, partialPath);
        }

        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
        {
            return new XSLTView(controllerContext, viewPath);
        }
    }
    public class XSLTView : IView
    {
        private readonly XslCompiledTransform _template;
        public XSLTView(ControllerContext context, string viewPath)
        {
            _template = new XslCompiledTransform();
            _template.Load(context.HttpContext.Server.MapPath(viewPath));
        }
        #region IView Members

        public void Render(ViewContext viewContext, System.IO.TextWriter writer)
        {
            XDocument xmlModel = viewContext.ViewData.Model as XDocument;
            if (xmlModel != null)
            {
                _template.Transform(xmlModel.CreateReader(), null, writer);
            }
            else throw new ArgumentException("Invalid xdocument");
        }

        #endregion
    }
}

After that , we should register the ViewEngine in Global.asax.

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

            RegisterRoutes(RouteTable.Routes);
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new XSLTViewEngine());
        }

Of course, we can sepecify the engin in controller.

        public ActionResult Index()
        {
            ViewResult result =  View(GetBooks());
            result.ViewEngineCollection = new ViewEngineCollection(){
               new XSLTViewEngine()
             };
            return result;
        }

posted on 2009-12-13 13:41  博览潇湘  阅读(268)  评论(0)    收藏  举报

导航