WebSurfer's Home

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

ASP.NET 開発サーバーと IIS

by WebSurfer 2011年11月18日 22:58

ASP.NET ベースの Web アプリケーションを開発する際、Visual Studio に搭載されている開発サーバーを利用されている方は多いと思います。

ASP.NET 開発サーバーの起動

余談ですが、この開発サーバーは、もともと Cassini という名前のサンプル Web サーバープログラムだそうで、今でも Microsoft のサイト ASP.NET Cassini Sample Web Server からソースコードを入手できます。(2012/1/8 追記: Cassini のダウンロードページがリンク切れになっていました。それに代わるものというわけではないですが、CassiniDev - Cassini 3.5/4.0 Developers Edition という CodePlex のサイトで改良版が提供されています)

開発サーバーは手軽で便利ですが、開発マシンで IIS が使えるのであれば、開発サーバーを開発に利用するのは避けたほうがいいと思います。

理由は、開発サーバーでは問題なく動いていても、IIS を使った本番環境に移すと動かないということがあるからです。

自分が認識している問題としては、以下があります。

  1. アクセス権: 開発サーバーの場合は PC にログインしているユーザーアカウントが持つアクセス権を使います。Administrator 権限でログインしていれば、ほぼ無制限に PC 内のリソースにアクセスできます。一方、実環境で IIS 上で動かす場合、リソースへのアクセス権は IIS のワーカープロセスのアカウント(IIS7 の場合、デフォルトで NETWORK SERVICE)が持つものになります。そのアクセス権には制限がありますので、ファイルが開けないとか書き込めないという問題が出てきます。
  2. 統合パイプラインモード: 開発サーバーには IIS7 の統合パイプラインモードの機能がありません(クラッシックモード相当になります)。また、統合パイプラインモードとクラシックモードとでは web.config での HTTP ハンドラ、HTTP モジュールの定義方法が異なりますので、定義の仕方によっては、HTTP ハンドラ、HTTP モジュールが動かない場合があります。
  3. 要求のフィルタリング: IIS7 で導入された 要求のフィルタリング requestFiltering は開発サーバーにはありません。それゆえ、カスタムエラーの表示などエラーハンドリングが異なります。
  4. MIME の種類: ファイルを要求した際、そのファイルの拡張子が IIS に定義済みの MIME の種類ではないと "HTTP エラー 404.0 - Not Found" を返します。よくある例が .flv や .mp4 ファイルで、開発サーバーでは再生できるが、IIS では再生できないという結果になります。(2013/4/20 追記)
  5. SSL: 開発サーバーには SSL 通信の機能がありません。したがって、SSL 通信下における試験ができません。(2012/1/8 追記)
  6. Session 0 分離: Windows Vista, Windows Server 2008 から Session 0 分離というセキュリティ対策がとられています(詳しくは、Windows でのサービスとドライバーへの Session 0 分離の影響 というページからダウンロードできる文書を参照)。つまり、ワーカープロセスは Session 0 で動いていて、それから起動されるアプリも Session 0 で動く。Session 0 は noninteractive なので、モーダルダイアログやフォームを表示することはできません(InvalidOperationException 例外がスローされます)。一方、ASP.NET 開発サーバーを使っている場合など、ワーカープロセスがログインしたユーザーのアカウントで動いている時は話が違ってきます。(2012/2/1 追記)
  7. 32-bit/64-bit の問題: これは逆に ASP,NET 開発サーバーで動かないケースで、利用しているライブラリが 64-bit 用の場合が問題になります。Visual Studio は 32-bit 版しか提供されていませんので、64-bit OS 上では WOW 上で 32-bit 動作します。その状態で、Visual Studio で Web アプリケーションを開発して ASP.NET 開発サーバで動作させた場合、Web アプリケーションは 32-bit で動作します。従って、x64 版の dll は動きません。例えば、Sharepoint の dll など x64 版 しかないものがあるそうですが、そのような場合は ASP.NET 開発サーバーでは動きません。(2013/9/5 追記)
  8. その他: IIS 用に用意された 拡張モジュール が利用できない。特に使えないと困るのが、SEO 対策に有効な URL Rewrite Module でしょうか。(2012/1/8 追記)

IIS 上で開発すれば、上記のようなトラブルは未然に防ぐことができます。(Visual Studio 2010 SP1 でリリースされた IIS Express を使うという選択肢があるようですが、自分は使ったことがないので、上記の問題の有無はわかりません。)(2012/10/27 追記:今さらながらですが IIS Express を使ってみました。1 項の「アクセス権」の問題は IIS Express では解決できません。その他にも問題があります。詳しくは IIS Express をインストールしました を見てください。)

XP, Vista, 7 など、サーバー OS でなくても、あるグレード以上なら IIS が標準で実装されています。ちょっと設定に時間はかかりますが、IIS をインストールして IIS 上で開発できます。

ただし、OS のグレードによっては IIS がインストールされていても機能に制限があり、デバッグができないものがあるので注意してください。

------ 2013/9/6 追記 ------

ASP.NET 開発サーバー、IIS Express、IIS の比較を書いた Microsoft の公式文書(MSDN ライブラリ)を紹介しておきます(URL 下記)。Visual Studio で IIS を使用して開発したい方は、そのページの下の方の「IIS をインストールして Visual Studio と連動するように構成」というセクションに設定方法のページへのリンクがありますので参考にしてください。

ASP.NET Web プロジェクト用の Visual Studio の Web サーバー

ASP.NET 開発サーバーの実態は何かは、以下のページが参考になると思います。

VS 2005やIISを使用せずにWebアプリケーションを実行するには?[VS 2005のみ]

WebDev.WebServer.EXE がある場所は Visual Studio のバージョンによって異なるので注意してください。上のページに書いてある場所は Visual Stidio 2005 の場合です。

Visual Studio 2008, 2010 の場合は以下のようになります。64-bit OS の場合は Program Files ⇒ Program Files (x86) になるはずです。

VS2008:
C:\Program Files\Common Files\microsoft shared\DevServer\9.0

VS2010:
C:\Program Files\Common Files\microsoft shared\DevServer\10.0

Tags: ,

ASP.NET

iframe の src 設定と SSL 通信

by WebSurfer 2011年11月15日 22:35

SSL (Secure Sockets Layer) 通信を行っているページで、"セキュリティで保護されているコンテンツのみ表示されます。"(IE9 の場合。他のバージョン、ブラウザではメッセージが異なります。)という警告が表示されることがあります。

SSL 通信での IE9 の警告

原因は、https:// で接続したページ内に https (SSL) と、http (非SSL) の接続が混在しているからです。例えば、そのページで使用している画像、CSS、JavaScript などのリソースへの参照を http で始まる URL で行っているケースです。

解決方法は、参照するファイルの URL を次のいずれかの形式に設定することです。

  • httpsで始まる絶対 URL パスを使う。
  • / (スラッシュ)で始まるサイトルート相対パスを使う。
  • 相対パスを使う。

上記のパスの具体的な例はそれぞれ以下のとおりです。

<img src="https://www.aaa.co.jp/images/sample.jpg" />
<img src="/images/sample.jpg" />
<img src="../images/sample.jpg" />

上記のようなケースは、html ソースを見れば気がつくので容易に対処できると思います。

気がつきにくいのが iframe の src 属性です。src を省略したり、http で始まる URL に設定したりすると警告が出ます。実は、自分は、これが問題になることすら知りませんでした。(汗)

特に問題なのは、動的に iframe がページに追加される場合です。さらに、ライブラリとして dll で提供されているカスタムコントロールの場合は、いくらソースを眺めていても、iframe は出てこないのでわかりません。

カスタムコントロールの具体的な例としては、AJAX Control Toolkit の AsyncFileUpload コントロールに使用されている iframe があります。このコントロール場合、src 属性には about:blank が設定されるのですが、about:blank も非 https と見なされるらしく、やはり警告が出ます。

解決方法は、KB261188 にあるように、iframe の src 属性の初期値を設定しない場合は、ダミー html ページを設定しておくことだそうです。

ただし、ダミーといっても存在しないファイルを設定するとサーバー側でエラーログが残るという話があるので(確かめたわけではありません)、中身は空でも実存するファイルを指定するのがよいそうです。

AJAX Control Toolkit の場合はソースが入手できますので、ソースを修正して再コンパイルするなりして解決できますが、そうでない場合は手の打ちようがないですね。

Tags: , ,

ASP.NET

TreeView.SelectedNode のサーバー側での特定

by WebSurfer 2011年11月13日 19:12

TreeView のノードをクリックするとポストバックが起こり、サーバー側で TreeView.SelectedNode プロパティでクリックされた TreeNode を取得できます。

TreeView の Node の選択

上の画像は、book というノードをクリックし、book ノードに含まれる子ノードの内 title ノードを取得してその Value を表示したものです。

そのコードは下に示したサンプルのとおりです。データとして使用している XML ファイルは MSDN ライブラリの チュートリアル : TreeView コントロールでの階層データの表示 のものです。

しかしながら、このコードでは、どの book ノードをクリックしても、表示されるのは一番上の book ノード下の title ノードの Value になってしまいます。

何故でしょう? 理由は以下の通りです。

どのノードがクリックされたかのサーバー側での判定は、root からクリックされたノードまでの Value をつなげた文字列を javascript:__doPostBack 関数の引数に設定し、ポストバックされた際にそれを取得して識別しています。

下のサンプルコードの例では、book ノードのハイパーリンクとして a 要素の href 属性に以下のように設定されます。

href="javascript:__doPostBack('TreeView1','sbookstore\\genre\\book')"

book ノードの Value はどれも同じ book ですので、__doPostBack 関数の引数はどの book ノードでも同じになってしまいます。それゆえサーバー側ではどの book がクリックされたか特定できません。だから、最初に該当する一番上の book が選択されたと判定してしまうようです。

解決策は、book ノードの Value が一意になるように TreeView の DataBindings に以下のように設定してやることです。

<asp:TreeNodeBinding DataMember="book"
    TextField="#Name" 
    ValueField="ISBN" />

考えてみれば、Windows アプリとは違って、ブラウザの画面に表示されているノードはインスタンスを指していないので、当たり前ですね。

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

  protected void TreeView1_SelectedNodeChanged(
    object sender, EventArgs e)
  {
    TreeNode selectedNode = TreeView1.SelectedNode;

    if (selectedNode.Text == "book")
    {
      foreach (TreeNode child in selectedNode.ChildNodes)
      {
        if (child.Text == "title")
        {
          Label1.Text = 
            "選択した本のタイトル: " + child.Value;
          break;
        }
      }
    }
    else
    {
      Label1.Text = String.Empty;
    }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <asp:TreeView ID="TreeView1" 
      runat="server" 
      DataSourceID="XmlDataSource1"
      OnSelectedNodeChanged="TreeView1_SelectedNodeChanged">
      <DataBindings>
        <asp:TreeNodeBinding DataMember="title" 
            TextField="#Name" 
            ValueField="#InnerText" />
      </DataBindings>
    </asp:TreeView>
    <asp:XmlDataSource ID="XmlDataSource1" 
      runat="server" 
      DataFile="~/App_Data/Bookstore.xml">
    </asp:XmlDataSource>
    <br />
    <br />
    <asp:Label ID="Label1" runat="server">
    </asp:Label>
  </div>
  </form>
</body>
</html>

Tags: ,

ASP.NET

About this blog

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

Calendar

<<  2024年4月  >>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar