Отображение представления в строку с последующим перенаправлением результатов в исключение - PullRequest
2 голосов
/ 19 июля 2009

Так вот в чем проблема: я создаю электронные письма, которые будут отправлены моим приложением, переводя страницы полного просмотра в строки и отправляя их. Это работает без каких-либо проблем, если я не буду перенаправлять на другой URL на сайте впоследствии. Всякий раз, когда я пытаюсь, я получаю «System.Web.HttpException: не удается перенаправить после отправки заголовков HTTP.»

Я полагаю, что проблема связана с тем, что я повторно использую контекст из действия контроллера, откуда поступает вызов для создания электронной почты. Более конкретно, HttpResponse из контекста. К сожалению, я не могу создать новый HttpResponse, который использует HttpWriter, потому что конструктор этого класса недоступен, а использование любого другого класса, производного от 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;
        }
    }

Ответы [ 3 ]

2 голосов
/ 15 мая 2010

Вот альтернативный метод для рендеринга представления в строку, которая никогда не приводит к выводу данных в ответ (поэтому это должно избежать вашей проблемы): http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/

Чтобы отобразить обычный вид вместо частичного, вам нужно изменить «ViewEngines.Engines.FindPartialView» на «ViewEngines.Engines.FindView».

2 голосов
/ 19 июля 2009

Вы должны будете инициировать новый запрос. Бит, ты действительно хочешь отправлять электронные письма синхронно? Если почтовый сервер не работает, пользователь может долго ждать.

Я всегда помещаю электронные письма в автономную очередь, и служба отправляет их по почте. Для этого вы можете использовать шаблонизатор Spark.

Еще один подход - не перенаправлять, а записывать страницу с метатегом перенаправления

0 голосов
/ 20 июля 2009

Посмотрите на службу MVC Contrib EmailTemplateService, которая делает именно то, что вам нужно.

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

Извините, Крис, не совсем уверен, о чем я думал, но я явно не читал вопрос. Хотя я не могу дать вам способ обойти это, я могу сказать вам, почему вы получаете ошибку - HttpResponse.Flush () отправляет заголовки перед сбросом содержимого в ваш фильтр. Это устанавливает флаг внутри ответа, чтобы при попытке перенаправления вы получили исключение.

Используя рефлектор, чтобы посмотреть на код внутри Flush, я не вижу ни одного чистого способа, чтобы вы могли обойти это без большого количества размышлений и других мерзостей.

...