【问题标题】:Rendering a view on-the-fly即时渲染视图
【发布时间】:2009-03-04 08:58:45
【问题描述】:

我正在开发一个 ASP.NET MVC 应用程序,它将向用户发送一封确认电子邮件。对于电子邮件本身,我想创建一个视图,然后渲染该视图并使用 .NET 邮件对象发送它。

如何使用 MVC 框架做到这一点?

【问题讨论】:

  • 我认为你的意思是 MVC,而不是 MCV
  • 不敢相信我连续打了 2 个错别字,而且都是同一个词!

标签: asp.net-mvc frameworks view render


【解决方案1】:

你基本上需要使用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 留给你。

【讨论】:

  • 此方法在经过一些修改后有效,但它导致以下错误:“发送 HTTP 标头后无法重定向”。这与它将 HTTP 标头向下发送到共享的 Response 对象有关,而不是它自己的流(对不起,我对 .NET HTTP 对象的理解还不是全部)。
  • 为什么会重定向?
  • ReleaseView 实际上是做什么的?真的很重要吗?如果我不打电话怎么办?
【解决方案2】:

根据我对 Richard 的回答的评论,这段代码确实有效,但它总是导致“发送 HTTP 标头后无法重定向”错误。

大量在 Google 周围挖掘并感到沮丧之后,我终于在这篇文章中找到了一些似乎可以解决问题的代码:

http://mikehadlow.blogspot.com/2008/06/mvc-framework-capturing-output-of-view_05.html

这家伙的方法是自己创建HttpContext。

我没有使用 MVCContrib BlockRenderer,而是将当前的 HttpContext 替换为新的 HttpContext,该新的 HttpContext 承载写入 StringWriter 的响应。

这种方法效果很好(一个小的区别是我必须创建一个单独的动作来渲染我的局部视图,但那里没有戏剧性)。

【讨论】:

    【解决方案3】:

    这对我有用:

    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);
                        }
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多