私はこのような何かを実装しましたが、それは依存性注入を使用してカスタムViewRenderingサービスを作成し、文字列にビューをレンダリングすることを利用したアプローチについてのラウンドを取ります。私はこのアプローチが好きです。なぜなら、私のアプリでは、電子メールのテンプレート、タグヘルパー、およびビューをコードで使用するために文字列にレンダリングする必要がある場合など、ビューを使用してモデルを渡すことができるからです。より動的な要素のビュー。あなたは、
public void ConfigureServices(IServiceCollection services)
{
...
services.AddTransient<IViewRenderService, ViewRenderService>();
...
}
最後に、あなたのStartup.csで次に
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());
}
}
ます:サービスの
public interface IViewRenderService
{
string RenderView(string viewName);
string RenderView<TModel>(string viewName, TModel model);
}
実施(重要な部分):
インターフェイスサービスを定義しますこのようなコード(この例ではコントローラ)でこれを使用してください:
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);
これは役に立ちます。
コンポーネント](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components)がオプションになる可能性があります。 –
、[ビューわからhelper.Partial' 'のようなヘルパーオブジェクトを呼び出すことはできませんが、MVCで
– juunas