読者です 読者をやめる 読者になる 読者になる

ASP.NET Webフォームプロジェクトでwebフォームの内容をhtmlファイルにしてダウンロードさせる

井上です。
いまだASP.NET Webフォームを用いているシステムも多々あると思います。
弊社もWebフォームのシステムがあり、そこで普段やらないことをやりましたのでそれをまとめておきます。
こんな処理を書くことはそうそう無いのですが何かの役に立つかもしれません。

環境

.NET Framework 4.5.1
ASP.NET Web Form
C#

目的

他システム(Linux/Apache)にアップロードするためのhtmlファイルをWebフォームを元に作成する。

方法

  1. HTML作成テンプレートとなるWebフォームを作成
  2. HTML作成用テンプレートを呼び出すWebフォームを作成
  3. 2で1に渡すパラメータの取得、session経由での引き渡しを行い、1を実行する
  4. 結果を加工しダウンロードさせる

Web Formを使うことによりListView等にバインドできたり、編集が比較的楽というメリットがあります。コードも見やすいです。
当然ですが、Web Formの結果であるため不要なタグを端折る必要があります。

コード

テンプレート

<html xmlns="http://www.w3.org/1999/xhtml">
<!-- headタグは出力対象 -->
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>    
    <title>hogehoge</title>
</head>
<body>
    <form id="form1" runat="server">
        <!-- body start -->
        <div class="templatestart"/>

        <!-- ここにいつも通りコードを書く。ー -->

        <div class="templateend"/>
        <!-- body end -->
    </form>
</body>
</html>

テンプレートのコードビハインド

using System;

public partial class hogehoge
{
    protected void Page_Load(object sender, EventArgs e)
    {        
        // セッションからパラメータ取得しバインド
        var data = (HogeHoge)Session["hogehoge"];

        this.DataBind();

        Session.Remove("HogeHoge");   
    }
}

HTML作成するWebフォームのコードビハインド

using System;
using System.Text;
using System.Web;

protected void CreateHtml_Click(object sender, EventArgs e)
{
    string url = "/template/hogehoge.aspx";

    // セッションに引き渡しパラメータを入れる
    Session.Add("hogehoge", new HogeHoge());

    // 実行・出力
    using (System.IO.StringWriter writer = new System.IO.StringWriter())
    {
        StringBuilder outputhtml = new StringBuilder();

        // テンプレートファイルを実行する
        HttpContext.Current.Server.Execute(url, writer, false);
        string html = writer.ToString().Replace(System.Environment.NewLine, "");

        // headタグ取得
        Regex regex = new Regex("<head>.*</head>");
        Match match = regex.Match(html);
        string headerhtml = match.Value;

        // 出力タグ取得
        regex = new Regex("<div class=\\\"templatestart\\\"/>(?<body>.*?)<div class=\\\"templateend\\\"/>");
        match = regex.Match(html);
        string bodyhtml = match.Groups["body"].Value;

        // html組み立て
        outputhtml.Append("<html>");
        outputhtml.Append(headerhtml);
        outputhtml.Append("<body>");
        outputhtml.Append(bodyhtml);
        outputhtml.Append("</body></html>");

        // ダウンロード
        Response.ClearContent();
        Response.ContentType = "text/html";
        Response.AddHeader("Content-Disposition", "attachment;filename=" + url.Substring(url.LastIndexOf('/') + 1).Replace(".aspx", ".html"));
        Response.Write(outputhtml.ToString());
        Response.End();
        Response.Flush();
    }
}

HttpContext.Current.Server.Executeで実行結果を受け取れますので、不要なタグを端折った後、ダウンロードさせています。