ASP.NETでHTMLを描画する場合、生成されたページ全体を保存したい場合がある。
データベースで、単一のテンプレから多数のページを作り出しているけど、その個々の実体ページが欲しい! といった用途が考えられる。
仕事で作ったサイトでこういう例があり、かなりハマった記憶がある。
具体的には、こうやった。
Partial Class SaveRenderPage
Inherits System.Web.UI.Page
Dim renderedOutput As StringBuilder
Dim strWriter As StringWriter
Dim tWriter As HtmlTextWriter
Dim outputStream As FileStream
Dim sWriter As StreamWriter
Dim filename As String
Dim nextPage As String
Private Sub Page_Load(sender As Object, e As EventArgs) Handles MyBase.Load
if (Not IsPostback()) then
Me.Page.DataBind()
With Me.Page.Request
if (Not .QueryString("Render") is Nothing) andAlso (.QueryString("Render")="True") then
Try
' HtmlTextWriterを用意
renderedOutput = New StringBuilder
strWriter = New StringWriter(renderedOutput)
tWriter = New HtmlTextWriter(strWriter)
' HtmlTextWriterに書込
Page.RenderControl(tWriter)
' Streamを用意
filename = Server.MapPath(".") & "\Rendered\" & "XXX.html"
outputStream = New FileStream(filename, FileMode.Create)
sWriter = New StreamWriter(outputStream)
' Streamに書出
sWriter.Write(renderedOutput.ToString( ))
sWriter.Flush( )
' 他ページへのリダイレクト
' そのままページ描画を続行すると、2重レンダリングで例外が発生するため
nextPage = "index.html"
Response.Redirect(nextPage)
Finally
'clean up
If (Not IsNothing(outputStream)) Then outputStream.Close( )
If (Not IsNothing(tWriter)) Then tWriter.Close( )
If (Not IsNothing(strWriter)) Then strWriter.Close( )
End Try
end if
End With
else
Response.Write("ポストバックなのでそのまま表示しますた")
End if
End Sub
End Class
青字のif文でわかるとおり、全く通常の表示ページと同じテンプレートで、パラメータを変えるだけでページの保存ができるようになっている。
また、ポイントは赤字の部分で、ページ表示をそのまま続行すると、二重レンダリングの例外が発生する。
このため、強制的に他ページにリダイレクトさせる手段が必要になる。
