Pregunta

Entonces aquí está el problema:Estoy creando correos electrónicos para que mi aplicación los envíe representando páginas de vista completa en cadenas y enviándolas.Esto funciona sin ningún problema siempre y cuando no redirija a otra URL del sitio después.Cada vez que lo intento, aparece "System.Web.HttpException:No se puede redirigir después de que se hayan enviado los encabezados HTTP."

Creo que el problema proviene del hecho de que estoy reutilizando el contexto de la acción del controlador de donde proviene la llamada para crear el correo electrónico.Más específicamente, HttpResponse del contexto.Desafortunadamente, no puedo crear una nueva HttpResponse que utilice HttpWriter porque el constructor de esa clase es inalcanzable y el uso de cualquier otra clase derivada de TextWriter hace que Response.Flush() arroje una excepción.

¿Alguien tiene una solución para esto?

    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;
        }
    }
¿Fue útil?

Solución

Tendrías que iniciar una nueva solicitud.Bit, ¿realmente quieres enviar correos electrónicos sincrónicamente de esta manera?Si el servidor de correo no funciona, el usuario podría estar esperando un buen rato.

Siempre pongo los correos electrónicos en una cola fuera de línea y tengo un servicio que los envía.Podrías considerar usar el motor de plantillas Spark para esto.

Otro enfoque es no redirigir sino escribir una página con una etiqueta meta de redirección.

Otros consejos

Aquí es un método alternativo para la representación miras a una cadena que nunca resulta en datos que se emite a la respuesta (por lo tanto, debe evitar el problema): http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial -Ver-a-string /

Para hacer una vista regular en vez de una vista parcial, tendrá que cambiar "ViewEngines.Engines.FindPartialView" a "ViewEngines.Engines.FindView".

Tener un vistazo a la MVC Contrib EmailTemplateService que hace exactamente lo que está después.

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

Lo siento Chris, no muy seguro de lo que estaba pensando, pero obviamente no leyó la pregunta. Mientras que no puedo dar una forma de evitar esto, puedo decir por qué usted está consiguiendo el error - HttpResponse.Flush () envía las cabeceras antes de vaciar el contenido en el filtro. Esto establece un indicador dentro de la respuesta para que cuando intenta redirigir a obtener la excepción.

El uso de reflector para mirar el código dentro de Flush, no puedo ver ninguna manera limpia para que usted pueda moverse esto sin mucha reflexión y otra porquería.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top