標籤:microsoft name 時代 為我 方式 它的 tostring dex href
一、前言
在有些項目需求上或許需要根據模板生產靜態頁面,那麼你一樣可以用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
ASP.NET Core中使用Razor視圖引擎渲染視圖為字串