はじめに
前回までにcontenteditable属性を用いたテキストエディタを出力できるHTMLヘルパーの作成方法を紹介しました。
今回は実際にそれに合わせたサーバーサイドの実装を説明します。
データクラス定義
まずは、以下のようなNewsクラスを利用することを前提で話を進めます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class News { [DisplayName("タイトル")] [Required(ErrorMessage = "{0}を入力してください。")] public string Title { get; set; } [AllowHtml] [DisplayName("内容")] [Required(ErrorMessage = "{0}を入力してください。")] public string Detail { get; set; } [DisplayName("更新日時")] [DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}")] [Required(ErrorMessage = "{0}を入力してください。")] public DateTime UpdateTime { get; set; } } |
このNewsクラスのDetailプロパティをテキストエディタとして利用可能にするためにAllowHtml属性を付与します。
この属性を付与しないとASP.NET MVCのフレームワークレベルで不正なタグや文字列をチェックする処理が実行されてエラーとなっていします。
エスケープ処理
上記のAllowHtml属性を付与したことで様々なタグが許可されてしまうため、Javascriptの埋め込みなども可能になってしまいます。そのため、不正なタグなどをエスケープする処理が必要となります。
入力内容をエスケープする手段は色々あると思いますが、今回はNSoupといったオープンソースを利用します。元はjsoupといったJava向けのライブラリを.NET向けに移植したもののようです。
Nugetなどには対応していなさそうなので手動でダウンロードして参照に加えます。
そしてNSoupを利用した以下のようなHTML変換クラスを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class SecureHtmlUtility { public static string GetSecuredHtmlFromString(string rawHtml) { //有効なタグ一覧を取得 var white = GetWhiteList(); //無効なタグをカットする var str = NSoupClient.Clean(rawHtml, white); return str; } private static Whitelist GetWhiteList() { var white = Whitelist.Relaxed; //fontタグのcolor,size属性を許可 white.AddTags(new[] { "font" }); white.AddAttributes("font", new[] { "color", "size" }); return white; } } |
Whitelistを用意して許可するタグを定義します。自前ですべて作ることも可能ですが、今回は初めから用意されたRelaxedを使用して、そこに許可する属性を追加します。
Relaxed以外にも組み込みの定義が何個か用意されていますので、どのようなタグが許容されるのかは本家のjsoupのところを見ればわかると思います。
<リンク>
上記のクラスを利用して無効なHTMLが入力された場合にカットするようにしてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class News { [DisplayName("タイトル")] [Required(ErrorMessage = "{0}を入力してください。")] public object Title { get; set; } [AllowHtml] [DisplayName("内容")] [Required(ErrorMessage = "{0}を入力してください。")] public object Detail { get; set; } [DisplayName("更新日時")] [DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}")] [Required(ErrorMessage = "{0}を入力してください。")] public DateTime UpdateTime { get; set; } public void EscapeHtml() { Detail = SecuredHtmlUtility.GetSecuredHtmlFromString(Detail); } } |
あとは以下のようにコントローラのアクションメソッド内でEscapeHtmlメソッドを呼び出しを行えば完了です。
1 2 3 4 5 6 7 8 9 10 11 12 |
[HttpPost] public ActionResult InputNews(News inputNews) { if (ModelState.IsValid) { //不正なHTMLをカット inputNews.EscapeHtml(); //略 } //略 } |
まとめ
4回に分けてフォントサイズなどの指定が可能なテキストエディタの作成を取り上げてきました。
まだまだ未完成な部分もありますので色々手を加えてみてください。