ワレコ
ワテの場合、ASP.NET MVCをやり始めて約3か月だ。
それまでは専ら(もっぱら) ASP.NET Web Formプロジェクトを使っていた。
その理由は何故かと言うと、ASP.NET Web FormはC#のデスクトップアプリのWeb Formによく似ているので取っつき易いからだ。
ASP.NET MVCと言うのが有るのは知っていたが、MVCと言うものが良く分からなかった。
MVC?
Microsoft Visual C++か?
いや違う。
Model View Controller
と言うシステム開発の設計手法の一つだ。
デザインパターンとも呼ばれる。
詳細は各自で調査して頂きたい。
当記事では、ASP.NET MVC初心者のワテが覚えた小技を備忘録として記事にした。
他にもC#やASP.NET、その他の小技を記事にしているので、興味ある人は参考にして下さい。
では、本題に入ろう。
ASP.NET MVCはとっても便利
ASP.NET の場合だとファイルタイプは .aspx が良く登場する。
一方、ASP.NET MVCの場合には拡張子 .cshtml が基本となる。
当初は、.cshtml って何やねん?
普通の .html と何が違うん?
と言う感じだったのだが、その仕組みを理解すると .cshtml はとっても便利な機能を持っている事に気づいた。
例えば、簡単な .cshtml ファイルの例
下のコードはVisual StudioでASP.NET MVCのプロジェクトを作成するときに自動で作られるabout.cshtmlファイルの中身だ。
@{ ViewBag.Title = "About"; } <h2>@ViewBag.Title</h2> <h3>@ViewBag.Message</h3> <p>Use this area to provide additional information.</p>
初めてこの .cshtml ファイルを見た人は戸惑うだろう。
何これ?
アットマーク@が沢山出て来るぞ?
実はワテも当初は戸惑った。
この
@変数名
は、丸カッコを付けて
@(変数名)
としても良い。
もし複雑な処理をC#の文法を使って書きたい場合には、
@{ ... C#の処理 ... }
としても良い。
ASP.NET MVCの動作
これらの動作はワテの理解で言うと以下のような仕組みになっている。
つまり、 .cshtml ファイルがブラウザーに表示される前にサーバーサイドで処理される。
その時に例えば
<h2>@ViewBag.Title</h2>
この部分は
<h2>About</h2>
に置換されるのだ。
この例では単純な文字列の置換だが、C#の処理を記述する事も可能である。
なおこの例に出て来る ViewBagはデフォルトで用意されているちょっと特殊?な(いや便利なと言うべきか)変数なので、各自で調査して頂きたい。
ちなみに、似たような変数にViewDataやTempDataと言うのもある。ViewData と ViewBagとTempData。
何で同じような仕組みが三つもあるのかはワテは良く分かっていない。
もし単純な変数を使って同じことをするなら、
@{ var Title = "About"; } <h2>@Title</h2> <h2>@(Title)</h2> @* 丸カッコで囲っても良い。ちなみにこの部分は .cshtmlファイルのコメント *@
となる。
そこで例えばもっと複雑な処理をしたい場合、例えば
「.cshtml ファイルで他の htmlファイル、cshtmlファイルの中身を読み込んで利用したい」
と言った事も可能だ。
例えば .cshtml ファイルの中で、こんな風にJavaScriptのコードがあり、msg 変数に html データを代入している部分があるとする(下図)。
<script> function myfunc() { var msg = '' + '<div class=\"myClass\">' + 'データ' + '</div>'; ... } </script>
そのhtml記述部分が複雑になって来たので、htmlの記述を別ファイルで定義する。
そのファイルを読み込んで msg に代入すればスッキリと書ける。
そうすると、後はその変数を使ってDOMにこのhtmlを追加するなども可能だ。JavaScriptでやっても良いし、jQueryでやっても良い。
実際にやってみる。
ASP.NET MVCで .cshtmlの中から他のファイルを読み込む手法
@{ var textAll = File.ReadAllText(Server.MapPath("~/Data/file.html")); } <script> function myfunc() { var msg = '@(textAll)'; ... } </script>
こんな感じか。
file.html の内容をサーバーサイドで変数 textAll に読み込んで、それを @(textAll) とするとその部分が読み込んだ文字列に置き換わる。
それをJavaScriptの文字列変数 msg に代入しているのだ。
なので ‘ ‘ で囲う必要がある。あるいは ” ” で囲っても良い。
しかしながら、このやり方だと問題が出る場合がある。
つまり、読み込んだ file.html の中に
- シングルクォーテーション ‘
- ダブルクオーテーション “
の文字が有る場合だ。
以下の例だと問題は無い。
textAll = "この文字列なら問題は無い。 "; // C#
でも例えば以下のデータをfile.htmlから読み込んだとすると、
textAll = "この文字列なら'問題が出る。"; // C#
それが以下の置換によって
var msg = '@(textAll)'; // JS
JavaScriptの変数を作成している部分は以下のようになる。
var msg = 'この文字列なら'問題が出る。'; // JS
この場合には、シングルクォーテーションが正しく対応していないので、文法エラーとなって実行時にエラーする。
クォーテーション記号の対策
要するに読み込んだ file.html の中にある
- シングルクォーテーション ‘
- ダブルクオーテーション “
をエンコーディングしてやれば良い訳だ。
ASP.NET encodingで検索するとエンコーディング関連関数は
HttpUtility.UrlEncode() HttpUtility.UrlPathEncode() HtmlHelper.AttributeEncode() HttpUtility.JavaScriptStringEncode()
沢山あるのだが、ここでは末尾のJavaScriptStringEncodeを使う。
MSDNの解説によると、
このメソッドは、文字列をエンコードします。 たとえば、単一引用符と二重引用符が含まれています \’ と \” 、エンコードされた文字列にします。
と言う事だ。
他のエンコーディング関数を使うと、これらの文字以外に
& | & | ampersand, U+0026 |
< | < | less-than sign, U+003C |
> | > | greater-than sign, U+003E |
“ | " | quotation mark, U+0022 |
‘ | ' | apostrophe, U+0027 |
などの文字変換が起こる場合がある。必要に応じて使い分けると良いが、今回は二種類のクオーテーション記号のみエンコード文字列に置換したい。
こんな風にすると行ける。
@{ var textAll = File.ReadAllText(Server.MapPath("~/Data/file.html")); textAll = HttpUtility.JavaScriptStringEncode(textAll); } <script> function myfunc() { var msg = '@Html.Raw(textAll)'; ... } </script>
最後に @Html.Raw() で出力するのがコツだ。
これを忘れると、< や > などの文字が htmlのタグと解釈されないので注意が必要だ。
cshtmlの中から他のcshtmlを読み込む
例えば Index.cshtml の中から他の _MyPartialView.cshtml を読み込む場合には、パーシャルビューを読み込む手法で簡単に出来る。
@Html.Partial("_MyPartialView")
もしそのパーシャルビューにデータを渡したい場合には第二引数に指定すれば良い。
例えば Index.cshtml の中で以下のようにパーシャルビューを埋め込む
@{ var viewDataDic1 = new ViewDataDictionary(ViewData);// ① var viewDataDic2 = new ViewDataDictionary(this.ViewData) { { "id", 5 }, {"model", Model} }; // ② } @Html.Partial("_MyPartialView", viewDataDic2)
コード Index.cshtml にパーシャルビューを埋め込む例
としてパーシャルビュー _MyPartialView を埋め込む。
①の場合には、Index.cshtml の ViewData を _MyPartialView.cshtml でも利用したい場合に利用する手法だ。ViewDataDictionaryのコンストラクタの引数に現在のViewDataを与えてnew で作成する。thisは省略しても良いみたい。
②の場合には、①に加えて、自前のデータも渡したい場合だ。Dictionary形式なのでkey、valueで好きな値を代入すれば良い。この例では、数字5と Index.cshtml の Model を_MyPartialView に渡している。valueにはstring、数値、object、Dictionary、Listその他、何でも渡せる。
もしIndex.cshtmlのViewDataをパーシャルビューに渡す必要が無いならViewDataDictionaryのコンストラクタの引数は空にしておいて、必要なデータを{・・・}内にkey, valueで与えれば良い。
一方、_MyPartialView.cshtml の中では、
@{ var id = ViewData["id"]; var Model = ViewData["model"]; }
で取り出して使えば良い。
ちなみに _MyPartialView.cshtml の先頭のアンダースコアには深い意味はない。
ワテの場合、パーシャルビューの場合には先頭にアンダースコアを付けるようにしているだけだ。
まとめ
ワレコ
今回は、ワテが猛勉強中のASP.NET MVCに於いて、cshtmlファイルの中で他のhtmlファイルやcshtmlファイルを読み込んで利用する方法を紹介した。
C#の ReadAllText, ReadAllLines を使うとサーバーサイドにあるファイルは簡単に読み取れる。
その読み取った文字列を JavaScript の中で html データとして利用するためには、JavaScriptStringEncode() や @Html.Raw() を使うと上手く行った。
もしもっとスマートな方法が有りましたら教えて下さい。
かなり安値で商品を買う – ASP.NET MVCで作成
2017年のゴールデンウイークを利用して便利なWEBサイトを作ってみた。
名付けて、
何が出来るかと言いますと、
Amazon.co.jp
楽天市場
ヤフーショッピング
の三つのショッピングサイトを同時検索して、商品を価格の安い順に表示出来ると言う、お買い物支援サイトです。
「最安価格サーチ」で、
「Visual Studioプログラミング」をかなり安値で探したい人は こちらから>
「C#プログラミング」をかなり安値で探したい人は こちらから>
もしお使い頂きまして何かご不明な点、改善案などありましたらお知らせ下さい。
余談
先ほど、ViewData と ViewBagとTempDataに関して何で同じような仕組みが三つもあるのかはワテは良く分かっていないと書いた。
から引用するとMVCの歴史は以下の通り。
Date | Version |
---|---|
10 December 2007 | ASP.NET MVC CTP |
13 March 2009 | ASP.NET MVC 1.0 |
16 December 2009 | ASP.NET MVC 2 RC |
4 February 2010 | ASP.NET MVC 2 RC 2 |
10 March 2010 | ASP.NET MVC 2 |
6 October 2010 | ASP.NET MVC 3 Beta |
9 November 2010 | ASP.NET MVC 3 RC |
10 December 2010 | ASP.NET MVC 3 RC 2 |
13 January 2011 | ASP.NET MVC 3 |
20 September 2011 | ASP.NET MVC 4 Developer Preview |
15 February 2012 | ASP.NET MVC 4 Beta |
31 May 2012 | ASP.NET MVC 4 RC |
15 August 2012 | ASP.NET MVC 4 |
30 May 2013 | ASP.NET MVC 4 4.0.30506.0 |
26 June 2013 | ASP.NET MVC 5 Preview |
23 August 2013 | ASP.NET MVC 5 RC 1 |
17 October 2013 | ASP.NET MVC 5 |
17 January 2014 | ASP.NET MVC 5.1 |
10 February 2014 | ASP.NET MVC 5.1.1 |
4 April 2014 | ASP.NET MVC 5.1.2 |
22 June 2014 | ASP.NET MVC 5.1.3 |
1 July 2014 | ASP.NET MVC 5.2.0 |
28 August 2014 | ASP.NET MVC 5.2.2 |
9 February 2015 | ASP.NET MVC 5.2.3 |
6 November 2014 | ASP.NET MVC 6.0.0-beta1 |
18 November 2015 | ASP.NET MVC 6.0.0-rc1 |
17 May 2016 | ASP.NET Core MVC 1.0.0-rc2 |
12 August 2016 | ASP.NET Core MVC 1.0.0 |
17 August 2016 | ASP.NET Core MVC 1.0.1 |
MVC1が出てからまだ10年程度。
MVC4, 5, 6 と短期間にバージョンアップしている。
最近ではMVC6やCore用のMVC1.0も出てきた。
つまりまあ、ワテの勝手な推測では、MVCを開発している人たちも、作りながら新しい仕様を決めていると思うので、似たような機能が複数出てきたりするのだと思う。
コメント