オンザフライでビューをレンダリングする
-
03-07-2019 - |
質問
ユーザーに確認メールを送信するASP.NET MVCアプリケーションを開発しています。メール自体については、ビューを作成し、そのビューをレンダリングして、.NETメールオブジェクトを使用して送信したいです。
MVCフレームワークを使用してこれを行うにはどうすればよいですか
解決 2
リチャードの答えに対する私のコメントによると、このコードは機能しましたが、常に「HTTPヘッダーの送信後にリダイレクトできません」というエラーが発生しました。
Googleを掘り下げてイライラしている多くのの後、この記事で、このトリックを実行しているように見えるコードをいくつか見つけました:
http://mikehadlow.blogspot .com / 2008/06 / mvc-framework-capturing-output-of-view_05.html
この男の方法は、独自のHttpContextを作成することです。
MVCContrib BlockRendererを使用するのではなく、単に現在のHttpContextを、StringWriterに書き込むResponseをホストする新しいHttpContextに置き換えます。
このメソッドは完全に機能します(マイナーな違いは、部分的なビューをレンダリングするために別のアクションを作成する必要がありましたが、ドラマはありません)。
他のヒント
基本的には IView.Render
を使用する必要があります。ビューを取得するには、 ViewEngineCollection.FindView
(デフォルトは ViewEngines.Engines.FindView
)を使用します。出力を TextWriter
にレンダリングし、後で ViewEngine.ReleaseView
を必ず呼び出してください。以下のサンプルコード(テストなし):
StringWriter output = new StringWriter();
string viewName = "Email";
string masterName = "";
ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, viewName, masterName);
ViewContext viewContext = new ViewContext(ControllerContext, result.View, viewData, tempData);
result.View.Render(viewContext, output);
result.ViewEngine.ReleaseView(ControllerContext, result.View);
string viewOutput = output.ToString();
viewData / tempDataはそのままにします。
これは私のために働いた:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
namespace Profiteer.WebUI.Controllers
{
public class SampleController : Controller
{
public ActionResult Index()
{
RenderViewAsHtml(RouteData.Values["controller"].ToString(),
RouteData.Values["action"].ToString());
return View();
}
private void RenderViewAsHtml(string controllerName, string viewName)
{
var vEngine = (from ve in ViewEngineCollection
where ve.GetType() == typeof(RazorViewEngine)
select ve).FirstOrDefault();
if (vEngine != null)
{
var view =
vEngine.FindView(
ControllerContext,
viewName, "_Layout", false).View as RazorView;
if (view != null)
{
var outPath =
Server.MapPath(
string.Format("~/Views/{0}/{1}.html",
controllerName, viewName));
using (var sw = new StreamWriter(outPath, false))
{
var viewContext =
new ViewContext(ControllerContext,
view,
new ViewDataDictionary(),
new TempDataDictionary(),
sw);
view.Render(viewContext, sw);
}
}
}
}
}
}