Я реализовал что-то подобное, но здесь используется подход, основанный на создании настраиваемой службы ViewRendering с внедрением зависимостей и использовании ее для рендеринга представления в строку. Мне нравится этот подход, потому что он позволяет моему приложению использовать представления для многих вещей, включая шаблоны электронной почты, taghelpers и любые другие случаи, когда мне нужно преобразовать представление в строку для использования в коде, а также позволяет мне передавать модель в вид для более динамичных элементов.
Интерфейс, определяющий службу:
public interface IViewRenderService
{
string RenderView(string viewName);
string RenderView<TModel>(string viewName, TModel model);
}
Реализация услуги (важная часть):
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;
using System;
using System.IO;
public class ViewRenderService : IViewRenderService
{
private readonly IRazorViewEngine _viewEngine;
private readonly ITempDataProvider _tempDataProvider;
private readonly IServiceProvider _serviceProvider;
public ViewRenderService(IRazorViewEngine viewEngine, ITempDataProvider tempDataProvider, IServiceProvider serviceProvider)
{
_viewEngine = viewEngine;
_tempDataProvider = tempDataProvider;
_serviceProvider = serviceProvider;
}
public string RenderView(string viewName)
{
var actionContext = GetActionContext();
var viewEngineResult = _viewEngine.FindView(actionContext, viewName, false);
if (!viewEngineResult.Success)
{
throw new InvalidOperationException(string.Format("Couldn't find view '{0}'", viewName));
}
var view = viewEngineResult.View;
using (var output = new StringWriter())
{
var viewContext = new ViewContext(
actionContext,
view,
new ViewDataDictionary(
metadataProvider: new EmptyModelMetadataProvider(),
modelState: new ModelStateDictionary()),
new TempDataDictionary(
actionContext.HttpContext,
_tempDataProvider),
output,
new HtmlHelperOptions());
view.RenderAsync(viewContext).GetAwaiter().GetResult();
return output.ToString();
}
}
public string RenderView<TModel>(string viewName, TModel model)
{
var actionContext = GetActionContext();
var viewEngineResult = _viewEngine.FindView(actionContext, viewName, false);
if (!viewEngineResult.Success)
{
throw new InvalidOperationException(string.Format("Couldn't find view '{0}'", viewName));
}
var view = viewEngineResult.View;
using (var output = new StringWriter())
{
var viewContext = new ViewContext(
actionContext,
view,
new ViewDataDictionary<TModel>(
metadataProvider: new EmptyModelMetadataProvider(),
modelState: new ModelStateDictionary())
{
Model = model
},
new TempDataDictionary(
actionContext.HttpContext,
_tempDataProvider),
output,
new HtmlHelperOptions());
view.RenderAsync(viewContext).GetAwaiter().GetResult();
return output.ToString();
}
}
private ActionContext GetActionContext()
{
var httpContext = new DefaultHttpContext();
httpContext.RequestServices = _serviceProvider;
return new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
}
}
Затем в вашем Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddTransient<IViewRenderService, ViewRenderService>();
...
}
Наконец, вы можете использовать это в таком коде (в этом примере контроллер):
public class TestController : Controller
{
private IViewRenderService viewRenderService;
public TestController(IViewRenderService _viewRenderService)
{
viewRenderService = _viewRenderService;
}
public async Task<IActionResult> Index()
{
// code
var stringOfView = viewRenderService.RenderView("EmailTemplate/EmailConfirmation");
// code that does something with the view as a string
return View();
}
}
Вы можете поместить свои представления в папку представлений в их собственной папке (в приведенном выше примере путь просмотра выглядит следующим образом: /Views/EmailTemplate/EmailConfirmation.cshtml)
Если вашему представлению требуется модель, вы должны передать ее так:
var stringOfView = viewRenderService.RenderView("folder/view", model);
Надеюсь это поможет!
person
Toby Lortz
schedule
08.06.2017
helper.Partial
, но не уверены в ядре asp.net - person Ehsan Sajjad   schedule 10.02.2017