这是一个基于jmal73's comment in Paris Polyzos' blog 的简单演示,如下所示:
1.自定义界面:
public interface IViewRenderService
{
Task<string> RenderToStringAsync(string viewName, object model);
}
2.实现接口:
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Routing;
public class ViewRenderService : IViewRenderService
{
private readonly IRazorViewEngine _razorViewEngine;
private readonly ITempDataProvider _tempDataProvider;
private readonly HttpContext _httpContext;
public ViewRenderService(IRazorViewEngine razorViewEngine,
ITempDataProvider tempDataProvider,
IHttpContextAccessor httpContextAccessor)
{
_razorViewEngine = razorViewEngine;
_tempDataProvider = tempDataProvider;
_httpContext = httpContextAccessor.HttpContext;
}
public async Task<string> RenderToStringAsync(string viewName, object model)
{
var actionContext = new ActionContext(_httpContext, new RouteData(), new ActionDescriptor());
var viewEngineResult = _razorViewEngine.FindView(actionContext, viewName, false);
if (viewEngineResult.View == null || (!viewEngineResult.Success))
{
throw new ArgumentNullException($"Unable to find view '{viewName}'");
}
var view = viewEngineResult.View;
using (var sw = new StringWriter())
{
var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
viewDictionary.Model = model;
var tempData = new TempDataDictionary(_httpContext, _tempDataProvider);
var viewContext = new ViewContext(actionContext, view, viewDictionary, tempData, sw, new HtmlHelperOptions());
viewContext.RouteData = _httpContext.GetRouteData(); //set route data here
await view.RenderAsync(viewContext);
return sw.ToString();
}
}
}
3.读取.cshtml文件并返回字符串:
public class HomeController : Controller
{
private readonly IViewRenderService _viewRenderService;
public HomeController(IViewRenderService viewRenderService)
{
_viewRenderService = viewRenderService;
}
public IActionResult Index()
{
var data = new Users()
{
UserId = 1
};
return View(data);
}
public async Task<IActionResult> Privacy()
{
var data = new Users()
{
UserId = 1
};
var result = await _viewRenderService.RenderToStringAsync("Home/Index", data);
return Content(result);
}
4.Index.cshtml:
@model Users
<form>
<label asp-for="UserId"></label>
<br />
<input asp-for="UserId" class="form-control" maxlength="4" />
<span asp-validation-for="UserId" class="text-danger"></span>
<input type="submit" value="create" />
</form>
5.注册服务:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IViewRenderService, ViewRenderService>();