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

ビューを文字列にレンダリングし、データが応答に出力されることのない代替方法を次に示します (したがって、問題を回避する必要があります): 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 に答える
2

新しいリクエストを開始する必要があります。ちょっと、本当にこの方法でメールを同期的に送信したいですか? メール サーバーがダウンしている場合、ユーザーはしばらく待機している可能性があります。

私は常にメールをオフライン キューに入れ、サービスにメールを送信しています。これには、Spark テンプレート エンジンの使用を検討してください。

もう 1 つの方法は、リダイレクトではなく、メタ リダイレクト タグを使用してページを書き出すことです。

于 2009-07-19T18:33:03.500 に答える
0

あなたが求めていることを正確に行うMVC Contrib EmailTemplateServiceを見てください。

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

申し訳ありませんクリス、私が何を考えていたのかよくわかりませんが、明らかに質問を読んでいませんでした. これを回避する方法を教えることはできませんが、エラーが発生する理由を説明できます. HttpResponse.Flush() は、コンテンツをフィルターにフラッシュする前にヘッダーを送信します. これにより、応答内にフラグが設定されるため、リダイレクトしようとすると例外が発生します。

Reflector を使用して Flush 内のコードを確認すると、多くのリフレクションやその他の煩わしさなしに、これを回避するためのクリーンな方法が見つかりません。

于 2009-07-20T04:11:04.127 に答える