WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

クライアント側検証の無効化

by WebSurfer 2015年2月17日 18:40

先の記事 コレクションのデータアノテーション検証 でユーザー入力の検証の話を書きましたが、デフォルトで有効になっているクライアント側での検証を無効にするにはどうすればいいかという話を書きます。

ユーザー入力の検証

これは、Visual Studio 2010 で MVC4 アプリを インターネットアプリケーション テンプレートで作った場合の話で、Visual Studio 2013 とか MVC5 とかでは違うかもしれませんのでご注意ください。

アプリケーションルート直下の web.config での以下の定義がされており、クライアント側での検証がアプリケーション全体で有効に設定されています。

<appSettings>
  ・・・中略・・・
  <add key="ClientValidationEnabled" value="true" />
  ・・・中略・・・
</appSettings>

クライアント側での検証を無効にしたいことがあるとすると多分特定の View だけでしょうから、その場合は当該 View のコードに下記を追加すれば OK です。

@{
  Html.EnableClientValidation(false);
}

クライアント側検証には EnableClientValidation の他に EnableUnobtrusiveJavaScript が使われていますが、stackoverflow の記事 によると、後者は Ajax にも使われていて、false にすると Ajax が動かなくなるとのことなので注意してください。

以上で話は終わりなのですが、それだけでは記事としてはちょっと面白くないので、上記に関連して調べたことを備忘録として書いておきます。(笑)

MVC4 の新機能として JavaScript / CSS ファイルの縮小化と結合処置の自動化機能があり、その機能を利用するため、App_Start フォルダの BundleConfig.cs ファイルに以下の定義がされています。

public class BundleConfig
{
  public static void RegisterBundles(BundleCollection bundles)
  {
    bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));

    bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                        "~/Scripts/jquery-ui-{version}.js"));

    bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.unobtrusive*",
                        "~/Scripts/jquery.validate*"));

    // ・・・中略・・・
  }
}

アプリケーションルート直下の Scripts フォルダには jquery-1.7.1.js, jquery.validate.js その他必要な jQuery 関係の外部スクリプトファイルが自動的に配置されます。

Global.asax には以下のコードが記述されており、アプリケーション起動時に外部スクリプトファイルのパスが ASP.NET の BundleCollection オブジェクトに登録されるようになっています。(詳しくは @IT の記事 Visual Studio 2012の新機能とASP.NET 4.5のコア機能 (3/4) を見てください)

public class MvcApplication : System.Web.HttpApplication
{
  protected void Application_Start()
  {
      // ・・・中略・・・

      BundleConfig.RegisterBundles(BundleTable.Bundles);

      // ・・・中略・・・
  }
}    

BundleCollection オブジェクトに登録した外部スクリプトファイルを参照するには、View で Scripts.Render メソッド を使用します。

具体的には _Layout.cshtml(Web Forms アプリのマスターページに相当)の @Scripts.Render("~/bundles/jquery") と View の @Scripts.Render("~/bundles/jqueryval") で以下の外部スクリプトファイルへの参照が HTML ソースに定義されます。

<script src="/Scripts/jquery-1.7.1.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>

(注)上記は <compilation debug="true" ... /> の場合です。debug="false" の場合はファイルの縮小化と結合処置の自動化機能が働いて以下のようになります。

<script src="/bundles/jquery?v=1A_Q..."></script>
<script src="/bundles/jqueryval?v=-tc2Q..."></script>

以上ような設定において、例えば Model にアノテーション属性を以下のように付与したとします。

public class Parent
{
  //・・・中略・・・

  [Required(ErrorMessage = "{0} は必須")]
  [StringLength(5, ErrorMessage = "{0} は {1} 文字以内")]
  [Display(Name = "Parent Name")]
  public string Name { get; set; }

  //・・・中略・・・
}

そして、View のコードを以下のように記述したとします。

<div class="editor-label">
  @Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
  @Html.EditorFor(model => model.Name)
  @Html.ValidationMessageFor(model => model.Name)
</div>

そうすると、クライアント側検証が有効の場合(Html.EnableClientValidation(true) の時)は、ASP.NET がレンダリングする HTML ソースは以下のようになります。

<div class="editor-label">
  <label for="Name">Parent Name</label>
</div>
<div class="editor-field">
  <input 
    class="text-box single-line" 
    data-val="true" 
    data-val-length="Parent Name は 5 文字以内" 
    data-val-length-max="5" 
    data-val-required="Parent Name は必須" 
    id="Name" 
    name="Name" 
    type="text" 
    value="" />
  <span 
    class="field-validation-valid" 
    data-valmsg-for="Name" 
    data-valmsg-replace="true">
  </span>
</div>

上記のように input 要素に付与された data-val* 属性に従って、参照された外部スクリプトに含まれる Unobtrusive(控えめな)JavaScript がクライアント側での検証を行うようになります。

一方、クライアント側検証を無効にした場合(Html.EnableClientValidation(false) の時)は ASP.NET がレンダリングする HTML ソースは以下のようになります。(注:外部スクリプトファイルへの参照は変わりません)

<div class="editor-label">
  <label for="Name">Parent Name</label>
</div>
<div class="editor-field">
  <input 
    class="text-box single-line" 
    id="Name" 
    name="Name" 
    type="text" 
    value="" />
</div>

クライアント側での検証はかかりませんがサーバー側で検証は行われ、検証結果が NG の場合は input 要素の直後に以下の span 要素が追加され、エラーメッセージ(上の画像の赤い文字)が表示されます。

<span class="field-validation-error">
  Parent Name は必須
</span>

Tags: ,

Validation

二重スラッシュを含む URL 書換

by WebSurfer 2015年1月23日 14:10

IIS の URL Rewrite モジュールを使用して aaaa/1/2/3 という URL を test.aspx?x=1&y=2&z=3 というように書き換えることを考えます。

URL の書き換え

この時、たと���ば上の画像のように 2 つ目の値をスキップした aaaa/1//3 という URL を test.aspx?x=1&y=&z=3(y に値がないところに注目)に書き換えたい場合はどうすればいいでしょうか?

IIS7 の URL Rewrite モジュールを使って、普通に(というか、あまり深く考えずに)書換ルールを作ると以下のようにすると思います。

<rewrite>
  <rules>
    <rule name="DoubleSlash">
      <match url="aaaa/(.*)/(.*)/(.*)" />
      <action 
        type="Rewrite" 
        url="test.aspx?x={R:1}&y={R:2}&z={R:3}" />
    </rule>
  </rules>
</rewrite> 

IIS マネージャーの「テストパターン」ダイアログ上で、[テスト対象データの入力(D):]テキストボックスに aaaa/1/2/3 とか aaaa/1//3 などのテストパターンを入力してテストすると、 {R:1}, {R:2}, {R:3} には期待通りの結果が得られます。

なので、ブラウザから aaaa/1/2/3 とか aaaa/1//3 などで呼んでも同様に aaaa/(.*)/(.*)/(.*) にマッチして、test.aspx?x=1&y=2&z=3 とか test.aspx?x=1&y=&z=3 に書き換えられると期待すると思います。

しかし、ブラウザから aaaa/1//3 で呼ぶとダメです。ダメな理由は、IIS が aaaa/1//3 を aaaa/1/3 に書き換えてしまうからです。詳しく書くと以下の通りです。

  1. ブラウザからは aaaa/1//3 で要求が出る。
  2. それを受けた IIS は aaaa/1//3 を aaaa/1/3 に書き換えてしまう。
  3. aaaa/1/3 が URL Rewrite モジュールに渡される。
  4. aaaa/1/3 は aaaa/(.*)/(.*)/(.*) にはマッチしない。マッチしないので書き換えは行われない。
  5. 書き換えが行われないので、IIS は aaaa/1/3 で指定されるリソースを探す。
  6. そのようなリソースは存在しないので HTTP エラー 404.0 - Not Found となる。

ちなみに、aaaa/1/2/3 であれば期待通り test.aspx?x=1&y=2&z=3 に書き換えられ、test.aspx ページ内でクエリ文字列は正しく取得できます。

上記 2 がどうして分かったかと言うと、6 で表示されるエラー画面で「要求された URL http://aspnet4site:80/aaaa/1/3」となっていたからです。(aspnet4site は自分の開発マシンで使っているホスト名です)

というわけで、上記 2 を何とかしないと URL Rewrite モジュールでは対処できないということになります。

それを何とかする手段が IIS Server Variables の UNENCODED_URL を使用して IIS が処理する前の URL を取得して、それに書換ルールを適用することです。

詳しい手順は Microsoft IIS.net の記事 URL Rewrite Module Configuration Reference の中の「Using server variables in rewrite rules」および「Using back-references in rewrite rules」というセクションが参考になると思います。

具体的な書換ルールのコードは、今回のケースでは以下のようになります。

<rewrite>
  <rules>
    <rule name="DoubleSlash">
      <match url="^aaaa/" />
      <action 
        type="Rewrite"
        url="test.aspx?x={C:1}&y={C:2}&z={C:3}" />
      <conditions>
        <add 
          input="{UNENCODED_URL}" 
          pattern="^/aaaa/(.*)/(.*)/(.*)" />
      </conditions>
    </rule>
  </rules>
</rewrite>

上記のルールで、aaaa/1/2/3 でも、aaaa/1//3 でも、aaaa//2/3 でも、 aaaa/// でも、その他全てのパターンで期待通り書き換えられるのを確認できました。

Tags: ,

Windows Server

CA 証明書の有効期限

by WebSurfer 2015年1月17日 18:51

先の記事 Active Directory 証明書サービス (AD CS) で紹介しました CA 証明書ですが、それには有効期限があって、手動で書き換える必要があります。

CA 証明書の書き換え

CA 証明書は AD CS の初回インストール時には自動的に発行されインストールされますが、有効期限はデフォルトで 5 年(AD CS のインストール時に変更できます)なので忘れたころに期限切れになります。

期限切れになっても自動的には更新されないので注意が必要なようです。(実は、自分は気がつかなかったです。(汗))

ブラウザで Web を通して http://localhost/certsrv から CA 証明書をダウンロードしても、古いものがダウンロードされるだけです。(実は、それで更新されるのではないかと思ってやってみたのですが、ダメでした。まぁ、考えてみれば当たり前ですね。(笑))

更新(書き換え)するには以下の操作が必要です。

  1. [管理ツール] から [証明機関] を開く。
  2. 証明機関管理コンソールの左のコンソール ツリーより CA 名(上の画像の例では bglb-SVR2K8-CA)を右クリックし、 [すべてのタスク] ⇒ [CA 証明書の書き換え] を選択。
  3. 証明書サービスを停止するか聞かれるので [はい] をクリック。
  4. 証明するキー (秘密鍵) を書き換えるか聞かれるので、 [いいえ] を選択し、 [OK] をクリック。

なお、有効期限を変更することは可能だそうです。具体的には Microsoft TechNet ブログの記事 CA 証明書の有効期限 を参照してください。

Tags:

Windows Server

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年3月  >>
252627282912
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar