您可以使用此类将视图渲染为字符串:
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;
namespace RenderView.Models
{
public class ViewRenderer
{
private readonly IRazorViewEngine _viewEngine;
private readonly ITempDataProvider _tempDataProvider;
private readonly IServiceProvider _serviceProvider;
private readonly IHttpContextAccessor _httpContextAccessor;
public ViewRenderer(
IRazorViewEngine viewEngine,
ITempDataProvider tempDataProvider,
IServiceProvider serviceProvider,
IHttpContextAccessor httpContextAccessor)
{
_viewEngine = viewEngine;
_tempDataProvider = tempDataProvider;
_serviceProvider = serviceProvider;
_httpContextAccessor = httpContextAccessor;
}
public async Task<string> RenderViewToStringAsync<TModel>(string viewNameOrPath, TModel model)
{
var actionContext = GetActionContext();
var view1 = _viewEngine.FindView(actionContext, viewNameOrPath, false);
if (!view1.Success)
{
view1 = _viewEngine.GetView("~/", viewNameOrPath, false);
if (!view1.Success)
throw new FileNotFoundException($"Couldn't find '{(object)viewNameOrPath}'");
}
var view2 = view1.View;
await using var output = new StringWriter();
var viewData = new ViewDataDictionary<TModel>((IModelMetadataProvider)new EmptyModelMetadataProvider(),
new ModelStateDictionary())
{
Model = model
};
var context = new ViewContext(actionContext, view2, (ViewDataDictionary)viewData,
(ITempDataDictionary)new TempDataDictionary(actionContext.HttpContext, this._tempDataProvider),
(TextWriter)output, new HtmlHelperOptions());
await view2.RenderAsync(context);
var stringAsync = output.ToString();
return stringAsync;
}
private ActionContext GetActionContext()
{
var httpContext = _httpContextAccessor?.HttpContext;
if (httpContext != null)
return new ActionContext(httpContext, httpContext.GetRouteData(), new ActionDescriptor());
var defaultHttpContext = new DefaultHttpContext
{
RequestServices = this._serviceProvider
};
return new ActionContext((HttpContext)defaultHttpContext, new RouteData(), new ActionDescriptor());
}
}
}
您应该将下面这几行添加到启动:
builder.Services.AddMvcCore().AddRazorViewEngine();
builder.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddScoped<ViewRenderer>();
按如下方式使用ViewRender类:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly ViewRenderer _viewRenderer;
public HomeController(ILogger<HomeController> logger, ViewRenderer viewRenderer)
{
_logger = logger;
_viewRenderer = viewRenderer;
}
public async Task<IActionResult> Index()
{
var renderedView =await
_viewRenderer.RenderViewToStringAsync<MyViewModel>("_MyView", new MyViewModel() { Id = 1 });
ViewData["RenderedView"]= renderedView;
return View();
}
public class MyViewModel
{
public int Id { get; set; }
}
}