2

所以这就是问题所在:我正在通过将完整视图页面呈现为字符串并发送它们来构建要由我的应用程序发送的电子邮件。只要我之后不重定向到站点上的另一个 URL,这将毫无问题。每当我尝试时,我都会收到“System.Web.HttpException:发送 HTTP 标头后无法重定向”。

我相信问题出在我正在重用来自控制器操作的上下文的事实,创建电子邮件的调用来自该操作。更具体地说,来自上下文的 HttpResponse。不幸的是,我无法创建一个使用 HttpWriter 的新 HttpResponse,因为该类的构造函数无法访问,并且使用从 TextWriter 派生的任何其他类都会导致 response.Flush() 本身引发异常。

有人对此有解决方案吗?

    public static string RenderViewToString(
        ControllerContext controllerContext,
        string viewPath,
        string masterPath,
        ViewDataDictionary viewData,
        TempDataDictionary tempData)
    {
        Stream filter = null;
        ViewPage viewPage = new ViewPage();

        //Right, create our view
        viewPage.ViewContext = new ViewContext(controllerContext,
            new WebFormView(viewPath, masterPath), viewData, tempData);

        //Get the response context, flush it and get the response filter.
        var response = viewPage.ViewContext.HttpContext.Response;
        //var response = new HttpResponseWrapper(new HttpResponse
        //    (**TextWriter Goes Here**));
        response.Flush();
        var oldFilter = response.Filter;

        try
        {
            //Put a new filter into the response
            filter = new MemoryStream();
            response.Filter = filter;

            //Now render the view into the memorystream and flush the response
            viewPage.ViewContext.View.Render(viewPage.ViewContext,
                viewPage.ViewContext.HttpContext.Response.Output);
            response.Flush();

            //Now read the rendered view.
            filter.Position = 0;
            var reader = new StreamReader(filter, response.ContentEncoding);
            return reader.ReadToEnd();
        }
        finally
        {
            //Clean up.
            if (filter != null)
                filter.Dispose();

            //Now replace the response filter
            response.Filter = oldFilter;
        }
    }
4

3 回答 3

2

您必须发起一个新请求。比特,你真的要这样同步发送邮件吗?如果邮件服务器关闭,用户可能会等待很长时间。

我总是将电子邮件放在离线队列中并让服务邮寄它们。您可以考虑为此使用 Spark 模板引擎。

另一种方法是不重定向,而是写出带有元重定向标签的页面

于 2009-07-19T18:33:03.500 回答
2

这是将视图呈现为字符串的另一种方法,该字符串永远不会导致数据输出到响应(因此它应该避免您的问题):http ://craftycodeblog.com/2010/05/15/asp-net-mvc -render-partial-view-to-string/

要呈现常规视图而不是局部视图,您需要将“ViewEngines.Engines.FindPartialView”更改为“ViewEngines.Engines.FindView”。

于 2010-05-15T17:35:18.117 回答
0

看看 MVC Contrib EmailTemplateService ,它完全符合您的要求。

http://mvccontrib.googlecode.com/svn/trunk/src/MVCContrib/Services/EmailTemplateService.cs

对不起,克里斯,不太确定我在想什么,但我显然没有读过这个问题。虽然我无法解决这个问题,但我可以告诉你为什么会出现错误 - HttpResponse.Flush() 在将内容刷新到过滤器之前发送标头。这会在响应中设置一个标志,以便在您尝试重定向时获得异常。

使用反射器查看 Flush 中的代码,如果没有大量反射和其他讨厌的东西,我看不出有任何干净的方法可以解决这个问题。

于 2009-07-20T04:11:04.127 回答