Во-первых, вы все равно, вероятно, захотите вернуть представление из вашего действия, поэтому возвращение EmptyResult не является лучшим; но вы поймете это, когда будете иметь дело с потоком страниц в процессе регистрации.
Я предполагаю, что вы хотите создать электронное письмо в формате HTML, используя уже созданное представление. Это означает, что вы хотите получить результат чего-то похожего на следующее:
public ActionResult CreateEmailView(RegistrationInformation info)
{
var userInformation = Membership.CreateNewUserLol(info);
return View(userInformation)
}
и отправьте это как текст письма. Вы можете повторно использовать свои взгляды и все эти забавные вещи.
Вы можете воспользоваться преимуществами инфраструктуры, создав собственный ActionResult и используя его для генерации текста.
Вот некоторый c # -подобный псевдокод, который может на самом деле компилироваться и работать. Во-первых, пользовательский ActionResult:
public class StringResult : ViewResult
{
public string Html { get; set; }
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (string.IsNullOrEmpty(this.ViewName))
{
this.ViewName =
context.RouteData.GetRequiredString("action");
}
ViewEngineResult result = null;
if (this.View == null)
{
result = this.FindView(context);
this.View = result.View;
}
ViewContext viewContext = new ViewContext(
context, this.View, this.ViewData, this.TempData);
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream))
{
// used to write to context.HttpContext.Response.Output
this.View.Render(viewContext, writer);
writer.Flush();
Html = Encoding.UTF8.GetString(stream.ToArray());
}
if (result != null)
{
result.ViewEngine.ReleaseView(context, this.View);
}
}
}
Это переопределяет базовый метод ExecuteResult (это код из базового метода, который я переопределяю; возможно, изменился в RC1) для рендеринга в поток, которым я управляю, вместо потока вывода ответа. Таким образом, он извлекает текст именно так, как он будет представлен клиентскому компьютеру.
Далее, как бы вы использовали это в действии контроллера:
public ActionResult CreateEmailView(RegistrationInformation info)
{
var userInformation = Membership.CreateNewUserLol(info);
// grab our normal view so we can get some info out of it
var resultView = View(userInformation);
// create our string result and configure it
StringResult sr = new StringResult();
sr.ViewName = resultView.ViewName;
sr.MasterName = resultView.MasterName;
sr.ViewData = userInformation;
sr.TempData = resultView.TempData;
// let them eat cake
sr.ExecuteResult(this.ControllerContext);
string emailHtml = sr.Html;
// awesome utils package, dude
Utils.SendEmailKThx(userInformation, emailHtml);
return resultView;
}
Я отображаю один и тот же вид дважды; в первый раз я рендерил это в поток, а второй раз я рендерил это нормально. Возможно, можно проникнуть в цепочку вызовов ViewResult где-нибудь еще и изменить работу Render, но беглый взгляд на код ничего не показывает. Несмотря на то, что инфраструктура довольно хороша, стек вызовов для отдельных частей процесса просто недостаточно детализирован, чтобы можно было легко изменить один шаг в процессе. Если бы они разбили ExecuteResult на несколько различных переопределяемых методов, мы могли бы изменить его с рендеринга на выходной поток на рендеринг в наш поток, не переопределяя весь метод ExecuteResult. Ну да ладно ....