ASP.NET Core中使用Razor视图引擎渲染视图为字符串
一、前言
在有些项目需求上或许需要根据模板生产静态页面,那么你一样可以用Razor语法去直接解析你的页面从而把解析的页面生成静态页,这样的使用场景很多,不限于生成静态页面,视图引擎为我们提供了模型到视图的代码或文本生成的能力。
本文章中采用的是ASP.NET Core MVC原生的方法;当然我在YOYOFx中也实现了这种视图引擎 ( https://github.com/maxzhang1985/YOYOFx/blob/master/AspNetCore/YOYO.AspNetCore.ViewEngine.Razor ) 。
当然在MVC 4、5的时代,我们也使用过如RazorEngine这样的第三方的视图引擎,那时候MVC中的Razor与框架耦合的比较紧密,第三方开源组件帮我们实现了在任意项目中使用Razor渲染视图为文本的方式;但是在.NET Core中 RazorEngine开源组件并没有移植过来,接下来我们还是要自食其力实现一个吧。
二、实现视图渲染器
其实在ASP.NET Core MVC中给我们提供了这样的方法,只是用起来不太方便,我们来对它进行一下封装。
框架早已经为我们提供了视图渲染的接口 IRazorViewEngine 通过它的FindView方法来查找视图及.cshtml文件,当然查找方法也与MVC中的视图路径规则是对应的,本来就是一个东西嘛:)
我们来一步步实现,首先我们建立一个视图渲染器的接口:
public interface IViewRenderService { Task<string> RenderToStringAsync(string viewName, object model); }
然后是实现类了,代码很简单一看就懂了:
public class ViewRenderService : IViewRenderService { private readonly IRazorViewEngine _razorViewEngine; private readonly ITempDataProvider _tempDataProvider; private readonly IServiceProvider _serviceProvider; public ViewRenderService(IRazorViewEngine razorViewEngine, ITempDataProvider tempDataProvider, IServiceProvider serviceProvider) { _razorViewEngine = razorViewEngine; _tempDataProvider = tempDataProvider; _serviceProvider = serviceProvider; } public async Task<string> RenderToStringAsync(string viewName, object model) { var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider }; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); using (var sw = new StringWriter()) { var viewResult = _razorViewEngine.FindView(actionContext, viewName, false); if (viewResult.View == null) { throw new ArgumentNullException($"{viewName} does not match any available view"); } var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = model }; var viewContext = new ViewContext( actionContext, viewResult.View, viewDictionary, new TempDataDictionary(actionContext.HttpContext, _tempDataProvider), sw, new HtmlHelperOptions() ); await viewResult.View.RenderAsync(viewContext); return sw.ToString(); } } }
三、如何使用
我们使用一个简单的例子来说明如何使用我们上面那个渲染器。
1、建立ViewModel
public class MyUserViewModel { public string Name { set; get; } }
2、建立视图
@model WebApplication6.Models.MyUserViewModel @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Render view to string</title> </head> <body> <div> @Model.Name </div> </body> </html>
3、修改HomeController
public class HomeController : Controller { private IViewRenderService _viewRenderService; public HomeController(IViewRenderService viewSendeRenderService) { _viewRenderService = viewSendeRenderService; } public async Task<IActionResult> Index() { var user = new MyUserViewModel { Name = "hello world" }; var result = await _viewRenderService.RenderToStringAsync("Home/Template1", user); return Content(result); } }
4、别忘了Startup
public void ConfigureServices(IServiceCollection services) { services.AddScoped<IViewRenderService, ViewRenderService>(); services.AddMvc(); }
四、写在最后
最后我只能说在ASP.NET Core中是万物皆DI啊,其实ASP.NET Core中的实现早就为我们想好了这些功能,只是改变了使用方式。
GitHub:https://github.com/maxzhang1985/YOYOFx 如果觉还可以请Star下, 欢迎一起交流。
.NET Core 开源学习群: 214741894
作者: YOYOFx
出处:https://www.cnblogs.com/maxzhang1985/p/12673160.html
版权:本文采用「署名-非商业性使用-相同方式共享 4.0 国际」知识共享许可协议进行许可。