ASP.NETのバインディング構文に関してインラインデータバインディング構文のメモ でまとめましたのですが、バインディング構文に : (コロン) をつけると HTML エンコードして出力をしてくれます。ASP.NETにはかなり長い時間かかわっているはずなのですが、つい最近知りました。

検証環境

  • ASP.NET 4.5

簡単なサンプルWebフォームを作成して動作確認をしてみます。

たとえば、次のような Webフォーム(aspx) を作成します。サンプルフォームのバインディング構文で <%# と <%: の2パターンでマークアップを生成するようにしています。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Repeater runat="server" ID="rptRepater" ItemType="WebApp.TestModel">
                <ItemTemplate>
                    <div>
                        :がないバージョン - バインドされた文字列にマークアップがあってもそのまま出力される(HTMLとして解釈される)
                <asp:Label runat="server" Text="<%# Item.Text %>" ID="Label1" />
                    </div>
                    <div>
                        <b>:があるバージョ</b>ン - バインドされた文字列に マークアップがあると エンコードされる(文字列として出力される) <br /><br />
                <asp:Label runat="server" Text="<%#: Item.Text  %>" ID="Label2" />
                    </div>
                </ItemTemplate>
                <SeparatorTemplate>
                    <hr />
                </SeparatorTemplate>
            </asp:Repeater>
        </div>
    </form>
</body>
</html>

サンプルのコードビハインドファイル(cs)は次のように作成します。コードビハインドファイルで Repeater コントロールにバインドするデータソースを作成しているだけです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApp
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            rptRepater.DataSource = TestModel.GenerateSample();
            rptRepater.DataBind();
        }
    }
    public class TestModel
    {
        public string Text { get; set; }

        public static IList<TestModel> GenerateSample()
        {
            List<TestModel> data = new List<TestModel>();
            data.Add(new TestModel { Text = "<h1 style='background-color:Green'>hello world</h1>" });
            data.Add(new TestModel { Text = "<h2 style='background-color:Yellow'>こんにちは 世界</h2>" });

            return data;
        }
    }
}

実行すると次のような結果になります。 <%# でバインドした場所はそのまま文字列が出力され HTMLのマークアップとして認識されています。一方 <%#: とコロンをつけた方は HTMLエンコードされて文字列として画面に出力されるようになります。

バインディング構文にコロンをつけることで簡単にjavascript インジェクション対策が行えるようになります。素敵です。