У меня есть система, которая генерирует электронные письма.Содержание частей этих электронных писем получено из ParialViews.В моем EmailController я хочу иметь возможность получать фрагменты HTML, которые формируют области шаблона электронной почты, вызывая их соответствующие действия и вставляя View HTML.
Я видел пост (ы) здесь ( Возвращать представление в виде строки в .NET Core ) относительно этого, но это не совсем работает ...
Приведенное ниже решение действительно находит и пытается получить представление HTML , но фактически не пытается выполнить действие контроллера представления.Поскольку представление является динамическим, это приводит к ошибке.
Итак, могу ли я выполнить ControllerB.Action
, перезапуская его результат в виде строки из ControllerA.Action
?
Myтекущая попытка: Служба:
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();
}
}
}
Starup.cs services.AddScoped<IViewRenderService, ViewRenderService>();
Контроллер A
private readonly IViewRenderService _viewRenderService;
public ReportController(...
IViewRenderService viewRenderService)
{
...
_viewRenderService = viewRenderService;
}
Звонок с контроллера A: var theHtmlString = await _viewRenderService.RenderToStringAsync("ControllerB/Action1", new { parameters = paramsmodel });