13. ファイルアップ掲示板

トップどんと来い! ASP.NET > 13. ファイルアップ掲示板

ポイントは2つだけ

ファイルをアップロードできる掲示板というのをたまに見ます。ただ、サーバにかける負担が大きいので、通常の掲示板ほど利用頻度は高くありませんし、おまけ程度の機能と言えるでしょう。
とはいっても、ファイルをアップロードすることができれば、かなり豪華っぽいですよね。

ということで、今回は「ファイルアップ掲示板」を作ることにします。しかし、本当に簡単なのでササッとできてしまいます。
重要なのはこれから述べる2つだけです。

まず1つは、「File Upload」コントロールです。
これまで HTML コントロールは使ってきませんでしたが、初めて HTML コントロールを使うことになります。

これを使うには、Web Matrix の左側のツールボックスの「HTML 要素」をクリックし、その中から探して貼り付けるだけです。
このコントロールは実に便利です。

<input id="File1" type="file" runat="server" />
これが File Upload コントロールのタグですが、非常に簡潔です。しかし、実際に表示してみると、
「参照」付きテキストボックス
であることがわかります。

このコントロールを利用することで、スマートにアップロードするファイルのパスを取得し、実際にアップロードできるのです。具体的な使い方はあとでコードを見てからにしましょう。

2つ目のポイントは 「form の属性」 です。
File Upload コントロールを利用し、ファイルをアップロードする場合、必ず
<form enctype="multipart/form-data" runat="server">
を指定しなければなりません。

form は元からありますので、そこに追加する形になります。この部分がどういう意味になるかは大して重要ではありません。
ファイルのアップロードの1つのポイントとして、この属性を知っておけば十分です。

ポイントは以上2つです。しかし、今度はちょっと工夫しなければならない点がありますよ。次の項目で見てみましょう。

掲示板からの修正点

カウンタ・掲示板を始めに作ったおかげで、そのコードを流用することができます。この掲示板も、以前作った掲示板にちょっと手を加えるだけです。

<p>
    ファイルパス: 
    <input id="File1" type="file" runat="server" />
</p>
<p>
    ファイルの保存名(拡張子まで):&nbsp; 
    <asp:TextBox id="TextBox4" runat="server"></asp:TextBox>
</p>
まずこのビジュアル部品を本文のテキストボックスの下にでもおきましょう。
上はさっき説明した「File Upload」コントロールで、下は単なるテキストボックスです。

string upfile = "";

if (File1.PostedFile != null)
{
    File1.PostedFile.SaveAs(Server.MapPath(".") + "\\images\\" + TextBox4.Text);
    upfile = "<a href=\"http://localhost/images/" + TextBox4.Text + "\">" + TextBox4.Text + "</a><br /><br />\r\n";
}
今度は Button1_Click() イベント内に記述します。

まず、if の条件式を見てください。「PostedFile」プロパティはそのつづりの通り、「送信されるファイル」で、これが「ヌル」すなわち何も指定していない場合以外は、条件式が true となります。

実際に保存するのは「SaveAs()」メソッドですが、これのつづりの通り「...として保存しろ」なので、引数にはファイル名をとります。
ここでは images フォルダを用意しておき、その中にガッポガッポ保存していくようにします。

ところで、アップロードしたファイルをほったらかしにしていてはいけません。掲示板ですから、その投稿内容に、「どこそこに保存したよ」とリンクを張っておかねばなりません。
そのリンクを張る作業の中心となるステートメントが次のコードです。

upfile はあらかじめ空文字にしてあるため、ファイルがアップロードされなければ upfile は空文字のままです。
しかし、保存されるとその在り処へのリンクを張るためのタグが代入されます。

ここで工夫が要るのがリンクの張り方です。ここでは Server.MapPath は利用できません。リンクの、http で始まるアドレスを取得するわけではないからです。
よって、あらかじめサーバの images フォルダを指定しておけばよいのです。ここではサンプルなので、自分の PC で動作させることを考えて上のようにしていますが、実際はサーバの images ディレクトリへのアドレスを記述します。

さて、最後の修正点はこの変数 upfile の値を本文に混ぜ込む作業です。
text = "<pre>" + upfile + TextBox3.Text + "</pre>";
掲示板のコードの中から text を探し、その中にちょこっと付け加えるだけです。

さて、最後に仕上げです。2つ目のポイントを忘れることなく修正してください。
<form enctype="multipart/form-data" runat="server">

ソース全貌

<%@ Page Language="C#" %>
<script runat="server">

    void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack){
            string path;
            string contents;
            System.IO.StreamReader streamReader;
    
            path = MapPath(".") + "\\" + "bbs.txt";
    
            streamReader = new System.IO.StreamReader(path);
            contents = streamReader.ReadToEnd();
    
            streamReader.Close();
    
            Label1.Text = contents;
         }
    }
    
    
    void Button1_Click(object Source, EventArgs e)
    {
       string path;
       string contents;
       string name,mail,text;
       string plus;
       string upfile = "";
    
       System.IO.StreamWriter streamWriter;
    
       path = MapPath(".") + "\\" + "bbs.txt";
    
       streamWriter = new System.IO.StreamWriter(path);
       contents = Label1.Text;
    
       if (File1.PostedFile != null)
       {
           File1.PostedFile.SaveAs(Server.MapPath(".") + "\\images\\" + TextBox4.Text);
           upfile = "<a href=\"http://localhost/images/" + TextBox4.Text + "\">" + TextBox4.Text + "</a><br /><br />\r\n";
    
       }
    
       name = TextBox1.Text;
       mail = "mailto:" + TextBox2.Text;
       text = "<pre>" + upfile + TextBox3.Text + "</pre>";
    
       plus = "<hr><b>お名前:</b><a href=\"" + mail + "\">" + name + "</a>" +
              " <b>投稿時間:</b>" + System.DateTime.Now.ToUniversalTime().AddHours(9).ToString() +
              "<br>" + text + "<hr>";
    
       if (TextBox3.Text == "")
           plus = "";
    
       contents = plus + contents;
       plus = "";
       Label1.Text = contents;
    
       streamWriter.Write("");
       streamWriter.Write(contents);
       streamWriter.Close();
    
       TextBox1.Text = "";
       TextBox2.Text = "";
       TextBox3.Text = "";
       TextBox4.Text = "";
    }

</script>
<html>
<head>
</head>
<body bgcolor="#e0e0e0">
    <h3>ファイルアップ掲示板 
    </h3>
    <form enctype="multipart/form-data" runat="server">
        <p>
            おなまえ:<asp:TextBox id="TextBox1" runat="server" Width="160px"></asp:TextBox>
        </p>
        <p>
            Eメール:<asp:TextBox id="TextBox2" runat="server" Width="160px"></asp:TextBox>
        </p>
        <p>
            <asp:TextBox id="TextBox3" runat="server" Width="368px" TextMode="MultiLine" Height="163px"></asp:TextBox>
        </p>
        <p>
            ファイルパス: 
            <input id="File1" type="file" runat="server" />
        </p>
        <p>
            ファイルの保存名(拡張子まで):&nbsp; 
            <asp:TextBox id="TextBox4" runat="server"></asp:TextBox>
        </p>
        <p>
            &nbsp;<asp:Button id="Button1" runat="server" Text="送信"></asp:Button>
        </p>
        <p>
            &nbsp;<asp:Label id="Label1" runat="server"></asp:Label> 
        </p>
    </form>
</body>
</html>
先ほども言ったように、localhost の部分は自分のサーバに合わせて変化させなければなりません。
これで、ファイルアップ掲示板も完成です。Web アプリってなんて簡単なんでしょう!!