Предоставление представления на лету
-
03-07-2019 - |
Вопрос
Я разрабатываю приложение ASP.NET MVC, которое отправит пользователю электронное письмо с подтверждением. Для самой электронной почты я хотел бы создать представление, а затем отрисовать его и отправить с использованием почтовых объектов .NET.
Как я могу сделать это с помощью инфраструктуры MVC?
Решение 2
Согласно моему комментарию к ответу Ричарда, этот код работал, но всегда приводил к ошибке «Не удается перенаправить после отправки заголовков HTTP».
После большого количества копания в Google и разочарования я наконец-то нашел в этой статье некоторый код, который, кажется, справляется с задачей:
http: //mikehadlow.blogspot .com / 2008/06 / MVC-основа захвата-вывода, из-view_05.html
Метод этого парня - создать свой собственный HttpContext.
Вместо того, чтобы использовать MVCContrib BlockRenderer, я просто заменяю текущий HttpContext новым, в котором размещается отклик, записывающий в StringWriter.
Этот метод работает отлично (небольшое отличие состоит в том, что мне пришлось создать отдельное действие для рендеринга моего частичного представления, но без драмы).
Другие советы
Вам в основном нужно использовать 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);
}
}
}
}
}
}