ASP.NET MVC自定义视图引擎ViewEngine 创建Model的专属视图

时间:2023-03-10 02:29:14
ASP.NET MVC自定义视图引擎ViewEngine 创建Model的专属视图

  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 = ; i < ; i++)
{
students.Add(new Student
{
Id = i + ,
Name = "Name" + Convert.ToString(i+),
Score = i +
});
}
} 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 可见效果