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 可见效果