自定義MVC檢視引擎ViewEngine 建立Model的專屬檢視

Darren Ji發表於2014-03-06

MVC內建的檢視引擎有WebForm view engine和Razor view engine,當然也可以自定義檢視引擎ViewEngine。本文想針對某個Model,自定義該Model的專屬檢視。

□ 思路

1、控制器方法返回ActionResult是一個抽象類
2、ActionResult的其中一個子類ViewResult,正是她使用IView例項最終渲染出檢視
3、需要自定義IView
4、IViewEngine管理著IView,同時也需要自定義IViewEngine
5、自定義IViewEngine是需要全域性註冊的

□ IView介面

public interface IView
{
    void Render(System.Web.Mvc.ViewContext viewContext, System.IO.TextWriter writer)
}

第一個引數ViewContext包含了需要被渲染的資訊,被傳遞到前臺的強型別Model也包含在其中。
第二個引數TextWriter可以幫助我們寫出想要的html格式。

□ IViewEngine介面

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

FindPartialView:在當前控制器上下文ControllerContext中找到部分檢視。
FindView:在當前控制器上下文ControllerContext中找到檢視。
ReleaseView:釋放當前控制器上下文ControllerContext中的檢視。

 

  模擬一個Model和資料服務類

   public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Score { get; set; }
    }
 
    public class DataAccess
    {
        List<Student> students = new List<Student>();
 
        public DataAccess()
        {
            for (int i = 0; i < 10; i++)
            {
                students.Add(new Student
                {
                    Id = i + 1,
                    Name = "Name" + Convert.ToString(i+1),
                    Score = i + 80
                });
            }
        }
 
        public List<Student> GetStudents()
        {
            return students;
        }
    }
 

 

  實現IView介面,自定義輸出html格式

using System.Collections.Generic;
using System.Web.Mvc;
using CustomViewEngine.Models;
 
namespace CustomViewEngine.Extension
{
    public class StudentView : IView
    {
 
        public void Render(ViewContext viewContext, System.IO.TextWriter writer)
        {
            //從檢視上下文ViewContext中拿到model
            var model = viewContext.ViewData.Model;
            var students = model as List<Student>;
 
            //自定義輸出檢視的html格式
            writer.Write("<table border=1><tr><th>編號</th><th>名稱</th><th>分數</th></tr>");
            foreach (Student stu in students)
            {
                writer.Write("<tr><td>" + stu.Id + "</td><td>" + stu.Name + "</td><td>" + stu.Score + "</td></tr>");
            }
            writer.Write("</table>");
        }
    }
}
 

 

  實現IViewEngine,返回自定義IView

using System;
using System.Web.Mvc;
 
namespace CustomViewEngine.Extension
{
    public class StudentViewEngine : IViewEngine
    {
 
        public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            throw new System.NotImplementedException();
        }
 
        public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            if (viewName == "StudentView")
            {
                return new ViewEngineResult(new StudentView(), this);
            }
            else
            {
                return new ViewEngineResult(new String[]{"針對Student的檢視還沒建立!"});
            }
        }
 
        public void ReleaseView(ControllerContext controllerContext, IView view)
        {
            
        }
    }
}
 

 

  HomeController

using System.Web.Mvc;
using CustomViewEngine.Models;
 
namespace CustomViewEngine.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var students = new DataAccess().GetStudents();
            ViewData.Model = students;
            return View("StudentView");
        }
 
    }
}
 

 

  全域性註冊

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
 
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
 
            ViewEngines.Engines.Add(new StudentViewEngine());
        }
    }

瀏覽/Home/Index效果:

1

相關文章