目次

Web開発(ASP.NET系)

はじめに

IISのバージョンとWindows OS

サーバーOSクライアントOSIIS
Windows Server 2019 IIS 10
Windows Server 2016Windows 10IIS 10
Windows Server 2012 R2Windows 8.1IIS 8.5
Windows Server 2012Windows 8IIS 8.0
Windows Server 2008 R2Windows 7IIS 7.5
Windows Server 2008Windows VistaIIS 7.0
Windows Server 2003 IIS 6.0
Windows XPIIS 5.1
Windows 2000 IIS 5.0

HTMLカラーコード

画面レイアウト(Bootstrap)

Bootstrap は、スマートフォンなどのモバイル端末にも対応し、レスポンシブデザインを採用した HTML, CSS, JavaScript フレームワークです。

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系軽量化、高速化をコンセプトにして開発。

メジャーアップデート!高速化したjQuery3.0の特徴
【翻訳まとめ】jQuery 3.0 アップグレードガイド

開始ページを指定する

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が呼ばれたとき下記のような流れで処理されます。

  1. /Views/_ViewStart.chtmlが読み込まれる
  2. /Views/Shared/_Layout.chtmlが読み込まれる(1.で指定しているから)
  3. 2.の_Layout.chtml中の@RenderBody()が呼ばれる(2. に記述されているから)
  4. /Views/Home/Index.chtmlが呼ばれる
  5. 必要に応じて@RenderSection()が呼ばれる

参照

データ受け渡し

ViewBag、ViewData、TempDataを使用する。
ASP.NET MVC の ViewData、ViewBag および TempData

ViewBag、ViewData

コントローラーから Viewへ(モデル以外に)データを渡す必要があります。データを渡す方法は2通りあります。

ViewBagとViewDataの違い

違いは型の安全性です。ViewData はキャストか型変換が必要となります。
ViewBagはMVC3からサポートされているものでMVC2以前のものはViewDataのみしか選択肢がなかった。
ViewData vs ViewBag vs TempData

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.ConfigdoAppInitAfterRestart はデフォルト 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がロードされ画像などの関連データの読み込みが完了後処理を実行」となります。

jQueryの読込み「ready」と「load」と「function」の順番について

「@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イベントを利用する方法

【jQuery】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とでる。

再現環境

対応として、互換表示にならないように常に標準モードになる<meta>タグを入れておく
<meta http-equiv=“X-UA-Compatible” content=“IE=edge”/>

IE対策:互換表示させない。

javascript のコールバック関数の引数指定

関数バインディング(bind())を使う

let sayHello = function(who) {
    alert('Hi ' + who + '!');
};
 
setTimeout(sayHello.bind(null, 'Mike'), 3000);

javascript のコールバック関数を引数付きで指定するには

フォントアイコンの検索

Font Awesomeのアイコンを日本語、英語、カタカナで簡単一発検索!
Search for Font Awesome