目次
Web開発(ASP.NET系)
はじめに
IISのバージョンとWindows OS
サーバーOS | クライアントOS | IIS |
---|---|---|
Windows Server 2019 | IIS 10 | |
Windows Server 2016 | Windows 10 | IIS 10 |
Windows Server 2012 R2 | Windows 8.1 | IIS 8.5 |
Windows Server 2012 | Windows 8 | IIS 8.0 |
Windows Server 2008 R2 | Windows 7 | IIS 7.5 |
Windows Server 2008 | Windows Vista | IIS 7.0 |
Windows Server 2003 | IIS 6.0 | |
Windows XP | IIS 5.1 | |
Windows 2000 | IIS 5.0 |
HTMLカラーコード
画面レイアウト(Bootstrap)
Bootstrap は、スマートフォンなどのモバイル端末にも対応し、レスポンシブデザインを採用した HTML, CSS, JavaScript フレームワークです。
- Twitter 社で開発され、最初は「Twitter Bootstrap」と呼ばれていましたが、現在は「Bootstrap」となりました。
- ライセンスは MIT License で、商用利用も可能です。
Bootstrap 5は、IE 11サポート対象外、jQueryを使わないよう設計されている。
参照
jQuery
2022/02/18現在の最新版は「jQuery 3.6.0」となる。
1.1x系 | Internet Explorer 8(IE8)の下位バージョンに対応 |
---|---|
2.x系 | IE9以上、Google Chrome、Firefox、Safariをはじめとしたモダンブラウザ用 |
3.x系 | 軽量化、高速化をコンセプトにして開発。 |
開始ページを指定する
Visual Studioのプロジェクトを選んで右クリック、「プロパティ」。
「Web」の「開始動作」の「ページを設定する」で、URLにあたる箇所(localhost:57210/以降)を設定する。
参照:スタートさせる最初のページ(URL)の指定
設定ファイルを読む
XML形式の設定ファイルを読み込み、DataTable型にセットする。
- ReadCofig
private DataTable ReadConfig() { DataSet ds = new DataSet(); string path = HttpContext.Current.Server.MapPath("~/App_Data/config.xml"); ; using (System.IO.StreamReader xml = new System.IO.StreamReader(path)) { ds.ReadXml(xml); } return ds.Tables[0]; }
- config.xml
<?xml version="1.0" encoding="utf-8" ?> <config> <data SystemType="HT" SystemName="部材受入れシステム" TableID="RESH003040" TableName="部材受入れ実績" Column="EC,ED" /> <data SystemType="HT" SystemName="部材払出しシステム" TableID="RESH003050" TableName="部材受入れ実績" Column="EC,ED" /> </config>
Viewが表示される基本的な流れ
HomeControllerのIndex Actionが呼ばれたとき下記のような流れで処理されます。
- /Views/_ViewStart.chtmlが読み込まれる
- /Views/Shared/_Layout.chtmlが読み込まれる(1.で指定しているから)
- 2.の_Layout.chtml中の@RenderBody()が呼ばれる(2. に記述されているから)
- /Views/Home/Index.chtmlが呼ばれる
- 必要に応じて@RenderSection()が呼ばれる
- @RenderBody()はテンプレートに1箇所のみ
- @RenderSection()は複数箇所でも可
参照
データ受け渡し
ViewBag、ViewData、TempDataを使用する。
ASP.NET MVC の ViewData、ViewBag および TempData
ViewBag、ViewData
ViewBagとViewDataの違い
違いは型の安全性です。ViewData はキャストか型変換が必要となります。
ViewBagはMVC3からサポートされているものでMVC2以前のものはViewDataのみしか選択肢がなかった。
ViewData vs ViewBag vs TempData
TempData
TempData の正体
TempDataは、「セッション状態(Session)」のラッパーライブラリです。
TempData の正体
ビューにデータを渡す
コントローラー側にてView(myModel)としてデータクラスを引数を渡す。
アイドル状態のワーカープロセスのスワップアウト
IISのアプリケーションプールのアイドル状態のタイムアウトは20分になっている。
この状態では、一定時間アイドル状態(アクセスのない状態)になったワーカープロセスは、タイムアウトされプロセスが停止していた。これにより、頻繁にアクセスのないWebサイトに関してはメモリの消費を抑えられるというメリットがあった。しかし、その分、タイムアウトされた後に来た最初のリクエストに関してはワーカープロセスを起動し直す分、応答に時間がかかっていた。
Windows Server 2012 R2とIIS 8.5の新機能
20分放置後だと初回のページ呼び出しに時間がかかる。対応としてアイドル状態のタイムアウトは 0分 にして回避する。
また、IISリセット後の初回のページ呼び出しに時間がかかるのは、後述の「ASP.NETアプリの起動を高速化(ウォームアップ)」で解消できる。
ASP.NETアプリの起動を高速化(ウォームアップ)
ASP.NETアプリケーションは初回のページ呼び出しがあった時に、アプリケーションの初期処理(ビルドなど)が実施されます。そのため、ファーストユーザーがページにアクセスした時に遅いと感じることがあります。
IIS 8.0 で標準搭載された Application Initialization機能を有効にしておくと、起動時にIISがアプリケーションを呼び出しておいてくれます。そのため最初のユーザーがアクセスした時の体感速度を向上させることができます。
Application Initialization
IIS は、既定でサービス開始直後にワーカープロセスを起動しません。ユーザーからのリクエストを受けてからワーカープロセスを起動し、その中で ASP.NET の初期処理などを行っています。結果、最初にリクエストを行うユーザーは、通常時と比べて応答に時間がかかる (初期化が完了するまで待たされる) こととなります。
この初回リクエストにかかるコストを軽減するための機能として Application Initialization が提供されており、自動的にワーカープロセスを起動させる機能と、仮想的な要求を内部的に発行し、該当の初期化処理を事前に終わらせる機能、の組み合わせで実現されています。
Application Initialization について
設定
[ASP.NET]Application InitializationでASP.NET Webアプリケーションを常時起動する
アプリケーションプール設定 | startMode=“AlwaysRunning” |
---|---|
Webサイト設定 | preloadEnabled=“true” |
Web.Config | doAppInitAfterRestart はデフォルト false skipManagedModules はデフォルト false |
- web.config
<system.webServer> <applicationInitialization> <add initializationPage="/api/S0100/S0102" /> </applicationInitialization> </system.webServer>
参照
調査
IIS applicationInitializationリクエストは内部で行われるため、W3Cログには表示されません。 ただし、Initializer.aspxページでリクエストを確認し、ユーザーエージェントを確認すると、「IIS Application Initialization Warmup」か「IIS Application Initialization Preload」が表示されます。
- Initializer.aspx
namespace SampleWebApp { public partial class Initializer : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //ダミーで10秒待つ System.Threading.Thread.Sleep(10000); // ログ・ファイルerr.logへの出力ストリームを生成 StreamWriter objSw = new StreamWriter( Server.MapPath("~/init.log"), true, Encoding.GetEncoding("Shift_JIS")); // 日付、ソース・コード、エラー・メッセージ、エラー原因となった // メソッドをタブ区切りテキストで記録 StringBuilder objBld = new StringBuilder(); objBld.Append(DateTime.Now.ToString()); objBld.Append("\t"); objBld.Append(Request.UserAgent); objSw.WriteLine(objBld.ToString()); objSw.Close(); } } }
- web.config
<system.webServer> <applicationInitialization remapManagedRequestsTo="Loading.html" skipManagedModules="false" doAppInitAfterRestart="false"> <add initializationPage="/Initializer.aspx" /> </applicationInitialization> </system.webServer>
- init.log
2020/03/04 16:51:00 IIS Application Initialization Warmup
参照
リソースのメッセージ使用
リソース用フォルダ(例 Resources)を作成する。
リソースファイル(例 Messages.resx)を作成して、アクセス修飾子を「Public」とする。
先頭に@usingでこのページで使用するリソースフォルダを指定する。
文字列を取得したい部分で、「@ResourceFile.name」と記述する。
@using mvctest.Resources; <input type="button" value=@Messages.cstButton1 > <!-- 行追加 --> <input type="button" value=@Messages.cstButton2 > <!-- 確定 --> <input type="button" value=@Messages.cstButton3 > <!-- 行削除 -->
リソースの多言語化
BINフォルダに頻繁な更新ファイルを置かない
ASP.NETは仕組み上、BINフォルダ内のファイルの更新を検知すると、アプリケーションを再起動するようになりセッション切れが発生する。
BINフォルダにはDLLなど滅多に更新されないファイルのみを配置する。
※頻繁に更新される出力ファイル(PDF)やログは、BINフォルダ以外の別フォルダに作成すること。
アプリケーションが再起動すると、初期状態になりASP.NETの呼出しに時間がかかってしまう。
VSデバッグ時の「これ以上ファイルがありません。」
Visual Studio上のWeb開発で「Internet Exploler」を使用してデバッグしようとすると、「これ以上ファイルがありません。」のメッセージ画面が表示されて、デバッグが出来なくなってしまう。
別のブラウザ(例 Chrome)にするとデバッグは出来る。
対応
タスクマネージャーで「iexplore.exe」を全て削除する。コマンドでは「taskkill.exe /F /IM iexplore.exe」
これで駄目なら、プロジェクトの右クリックメニューで「クリーン」を実行する。
これでも駄目なら、PC再起動
there are no more files error using express 2012 for web
これでも駄目なら、IIS Expressをコマンドラインで動作確認してみる
開発用 Web サーバー IIS Express をコマンドラインから使用する方法
これでも駄目なら、ソリューションファイルとプロジェクトを一から作り直す。
リソースが見つかりません
POSTを使用すると、「リソースが見つかりません」というエラーが表示されます。
GetSQLDataのコントローラーが見つからないか、IControllerを実装していません。
原因としてコントローラーの指定が間違っている。
- 例
postAjax('GetSQLData', JSON.stringify(param), process); ↓ postAjax('/Home/GetSQLData', JSON.stringify(param), process);
発行先だと動作しない
Visual Studio上のWebブラウザでは動作したが、発行した環境ではエラーになる。
Visual Studio上ではIIS Expressで動かしていた。
URL先が違う
開発では、localhost 直下であったが、発行した環境では、仮想ディレクトリ のエイリアス(例 Test)が付く
http://localhost/Home/Schedule ↓ http://localhost/Test/Home/Schedule
先頭の"/"は不要だった。 Redirect("/Home/" + page) ↓ Redirect("Home/" + page)
jQuery.ajax({ url: '/Home/' + method, ↓ jQuery.ajax({ url: method,
Windowsサービスの操作ができない
Visual Studio上のWebブラウザでは動作していたので、権限の問題。
対象1
IISのアプリのアプリケーションプールの詳細設定にある、「アプリケーションID」を「ApplicationPoolIdentity」から「LocalSystem」に変更する。
Local System アカウントは Web サーバーの Administrators グループに含まれるアカウントである。
IIS 7 のアプリケーションIDってなんや? No5
対象2
IISのアプリのアプリケーションプールの詳細設定にある、「アプリケーションID」を「ApplicationPoolIdentity」のまま。
web.configに「identity impersonate=“true”」を追加する。
ASP.NETにはユーザの偽装の機能があり、アクセス権が絡むときに使用する。
- web.config
<system.web> <compilation debug="true" targetFramework="4.6"/> <httpRuntime targetFramework="4.5.2"/> <identity impersonate="true" userName="Administrator" password="xxxxxxx" /> </system.web>
Tips
非同期POST後のリダイレクト
jQuery.ajaxのPOSTでdataTypeをjsonにした状態で、リダイレクト(RedirectToAction)しようとするとHTMLをJSONに変換しようとしてエラーとなる。
エラー「200 SyntaxError: Unexpected token '<', “<!DOCTYPE ”… is not valid JSON」
対応
Json形式でリダイレクトするURLを返し、jQuery.ajaxのPOST側でwindow.location.hrefにURLを指定してリダイレクトさせる。
Index.d.tsにてRecordが見つかりません
TypeScriptのバージョンが古いとのことで、NuGetで最新版2.9.2を入れたがエラーが解消されなかった。
Cannot find name 'Record' in index.d.ts build error
Build error “Cannot find name 'Record'” with bootstrap 4
TypeScript for Visual Studio 2015 をインストールしたらエラーが解消された。
https://www.microsoft.com/ja-JP/download/details.aspx?id=48593
ふわっと表示して徐々に消えるメッセージ
<div id="alert" class="alert alert-danger mt-2" role="alert"><span class="fa fa-exclamation-circle pr-2"></span>@ViewBag.MsgError</div> <script type="text/javascript"> $('#alert').fadeIn(1000).delay(3000).fadeOut(2000); </script>
textarea の横幅が指定したサイズにならない
- 例
<textarea style="width:1015px" rows="5" class="ml-3">
原因は site.css を読み込んでいるため 280pxで横幅が固定されていた。
site.cssはASP.NETプロジェクト固有のスタイルシートです。
AJaxで複数のJSONデータをPOSTする
POST用に専用のViewModelを作成すればいい。
[ASP.NET MVC] JSONを受け取る、JSONを返す
AJax使用方法
AJaxでローディング画像の表示
非同期通信の開始/終了/成功/失敗のタイミングで処理を実行するには?(ajaxXxxxx)
<form> <div id="spinner" style="display:none;"><img src="ajax-loader.gif" /></div> <ul id="result"></ul> </form> <script> $(document) .ajaxStart(function() { $('#spinner').show(); }) .ajaxStop(function() { $('#spinner').hide(); }); </script>
フォントのwoffとwoff2ファイルのMIME登録
IIS上でbootstrapのwoffとwoff2ファイルを使う際には注意が必要。デバッグ時にはエラーにならない。
MIMEにフォントの「woff」と「woff2」の拡張子が登録されていないため取得できない旨の404エラーが出る。
IISでMIMEの追加をすればよいが、設定忘れも考慮してWeb.configに設定を追加する方法がある。
直下のweb.configに下記の設定を追加する。
- web.config
<system.webServer> <staticContent> <remove fileExtension=".woff" /> <mimeMap fileExtension=".woff" mimeType="application/font-woff" /> <remove fileExtension=".woff2" /> <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" /> </staticContent> </system.webServer>
Windows Server 2008R2のIIS 7.5 には、「woff」と「woff2」が未登録
Windows Server 2012R2のIIS 8.5 には、「woff2」が未登録
"~"チルダはルートURL
jQueryの読込みの順番
「ready」と「load」の違いについて
この2つは読込まれるタイミング違ってきております。
どういった動作をしているのか
「ready」は「ready関数を使用してDOMがロードされて操作・解析が可能になったタイミングで関数を実行」でした
「load」は「DOMがロードされ画像などの関連データの読み込みが完了後処理を実行」となります。
「@Scripts」と「@Style」が使えない
@Scripts.Render と @Style.Render を使いたいがコマンドを認識してくれない。
NuGetで「Microsoft.AspNet.Web.Optimization」をインストールする。
MVCの場合、Viewにあるweb.configに下記の設定を追加する。
- Web.config
<add namespace="System.Web.Optimization" />
これを使うには「App_Start\BundleConfig.cs」ファイルにJavaScript/CSSのバンドル・ファイルの登録が必要となる。
submitイベントを利用する方法
@using (Html.BeginForm("Index", "Login", FormMethod.Post, new { id = "fmLogin" })) <script type="text/javascript"> $('#fmLogin').on('submit', function () { // ローディング画面表示 ShowLoading(); }); </script>
IE11で正しくレイアウトされない
互換性表示されると、IE7モードで動作する。IISログにcompatible;+MSIE+7.0とでる。
再現環境
- インターネットオプション[接続][LANの設定][プロキシ設定]にプロキシサーバを登録。
- 詳細設定から、対象のIPアドレスが例外になるように登録。
- 互換表示設定で「イントラネットサイトを互換表示で表示する」チェック有り。
対応として、互換表示にならないように常に標準モードになる<meta>タグを入れておく
<meta http-equiv=“X-UA-Compatible” content=“IE=edge”/>
javascript のコールバック関数の引数指定
関数バインディング(bind())を使う
let sayHello = function(who) { alert('Hi ' + who + '!'); }; setTimeout(sayHello.bind(null, 'Mike'), 3000);
フォントアイコンの検索
Font Awesomeのアイコンを日本語、英語、カタカナで簡単一発検索!
Search for Font Awesome