zoukankan      html  css  js  c++  java
  • 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  

  • 相关阅读:
    【2018.05.05 C与C++基础】C++中的自动废料收集:概念与问题引入
    【2018.04.27 C与C++基础】关于switch-case及if-else的效率问题
    【2018.04.19 ROS机器人操作系统】机器人控制:运动规划、路径规划及轨迹规划简介之一
    March 11th, 2018 Week 11th Sunday
    March 10th, 2018 Week 10th Saturday
    March 09th, 2018 Week 10th Friday
    March 08th, 2018 Week 10th Thursday
    March 07th, 2018 Week 10th Wednesday
    ubantu之Git使用
    AMS分析 -- 启动过程
  • 原文地址:https://www.cnblogs.com/maxzhang1985/p/6268777.html
Copyright © 2011-2022 走看看