ASP.NET 4.8のGridViewで起きるItemTypeエラーを解消する方法

ASP.NET Webアプリケーションを開発していて、GridViewのItemTypeエラーに直面したことはありませんか?特に.NET Framework 4.8で構築したプロジェクトを非アップデート可能な事前コンパイルにすると、予期せぬエラーが生じることがあります。この記事では、その原因と対策を丁寧に解説します。

ASP.NET 4.8環境でGridViewのItemTypeエラーが起きる理由

ASP.NET 4.5以降の機能として導入された強く型付けされたデータバインディングは、GridViewやListViewなどでItemTypeを指定すると、サーバーサイドでプロパティへ安全にアクセスできる便利な機能です。しかし、.NET Framework 4.8であっても、特定のビルド設定やプロジェクト構成によっては、コンパイラがこのItemTypeプロパティを認識できずにエラーを引き起こすことがあります。

事前コンパイル(aspnet_compiler.exe)とアップデート可能・不可能設定

ASP.NETでは大きく分けて以下の2通りの事前コンパイルオプションを指定できます。

オプション説明
-u (アップデート可能)一部のASP.NETページを更新できるようにコンパイルする。ページ単位で再コンパイルされる余地を残すため、型情報が動的に解決される場合がある。
-c (アップデート不可能)すべてのASP.NETページを完全にコンパイルした状態にする。ページファイル(ASPX, ASCXなど)はプレースホルダとなり、変更が加えられた場合、通常の手順で再展開が必要。

アップデート可能(-u)だと問題なくビルドが通るのに対し、アップデート不可能(-c)にするとItemTypeの存在を見つけられずにコンパイルエラーが発生するケースがあります。これはプロジェクトの設定や参照方法、またはASP.NETのコンパイラが内部的にどのライブラリを読み込んでいるかによる不一致が背景にあると考えられます。

GridViewにおけるItemTypeの使い方

従来のEval/Bindと強く型付けされたデータバインディングの違い

ASP.NET Web Formsでデータを扱う際、従来の手法はEval()Bind()を用いるものでした。たとえば下記のようなコードです。

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
    <Columns>
        <asp:BoundField DataField="Name" HeaderText="名前" />
        <asp:BoundField DataField="Age" HeaderText="年齢" />
    </Columns>
</asp:GridView>

ここにデータバインドを行う場合、コードビハインド側(C#)でGridView1.DataSource = 取得したデータ;とし、GridView1.DataBind()を呼び出します。さらに、テンプレート列を使ったパターンでは下記のようにEvalを利用します。

<asp:TemplateField HeaderText="メールアドレス">
    <ItemTemplate>
        <%# Eval("Email") %>
    </ItemTemplate>
</asp:TemplateField>

一方、ASP.NET 4.5以降の強く型付けされたデータバインディングを使うと、GridViewの宣言でItemTypeを指定し、テンプレート内ではItemオブジェクトを通じてプロパティに直接アクセスできます。例えば以下のようになります。

<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" 
    ItemType="MyProject.Models.Person" SelectMethod="GetPersonList">
    <Columns>
        <asp:TemplateField HeaderText="名前">
            <ItemTemplate>
                <%# Item.Name %>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="年齢">
            <ItemTemplate>
                <%# Item.Age %>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

上記のように書くと、コードビハインドでデータソースを直接指定する代わりにSelectMethodでデータ取得メソッドを紐づけたり、マークアップ部分でItem.Nameなど型の補完を受けながらプロパティ参照ができるようになります。このメリットは、開発時の入力補助だけでなく、型の不整合を抑止できる点にあります。

なぜ「GridViewにItemTypeが存在しない」エラーが起きるのか

原因1:コンパイラが古いアセンブリを参照している

.NET Framework 4.8をインストールしていても、aspnet_compiler.exeの呼び出しパスが意図しないバージョンを指しているケースがあります。特に複数の.NETバージョンが混在するサーバーや開発環境だと、C:\Windows\Microsoft.NET\Framework\v4.0.30319 以外に予期せず参照されている場合があります。

原因2:Webサイト形式 vs Webアプリケーション形式の差異

ASP.NETにはプロジェクトの構造としてWebサイト形式Webアプリケーション形式があります。Webサイト形式は動的コンパイルを前提としており、事前コンパイル時に内部で型参照に関する問題が起こりやすいとされています。Webアプリケーション形式だとビルドプロセスが明示的で、通常のC#プロジェクトのようにコンパイルが行われるため、問題が発生しにくい傾向があります。

原因3:Web.configまたはプロジェクトのターゲットフレームワーク設定不備

.NET Framework 4.8を利用しているつもりでも、実際のWeb.configの設定や.csprojファイルの&lt;TargetFrameworkVersion&gt;に誤りがあれば、コンパイル時に古いバージョンの参照が使われる可能性があります。また、&lt;pages&gt;セクションでSystem.Web.ModelBindingをインポートしていない場合、強く型付けされたバインディング機能がうまく動作しないこともあります。

解決策と回避策

対処1:コンパイラのバージョンを確認

コマンドプロンプトやPowerShellなどでaspnet_compiler.exeのフルパスを指定し、バージョン情報を確認してみましょう。以下のようにバージョンを調べるコマンドが使えます。

& 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe' /?

出力される情報から、適切なパッチが当たった.NET Framework 4.8環境であることを確かめてください。もしも別のフォルダ上の古いコンパイラを使っている場合は、正しいパスへ修正するか、環境変数PATHなどを調整して最新のコンパイラを指すようにしましょう。

対処2:Web.configの設定再確認

Web.configファイルに下記のような設定があるかチェックしてみてください。

<configuration>
  <system.web>
    <compilation targetFramework="4.8" strict="false" debug="false" />
    <pages enableViewState="true" validateRequest="true" pageParserFilterType="System.Web.UI.PageParserFilter">
      <namespaces>
        <add namespace="System.Web.ModelBinding" />
        <!-- 必要に応じて他の名前空間も -->
      </namespaces>
    </pages>
  </system.web>
</configuration>

targetFrameworkが正しく4.8になっているか、System.Web.ModelBindingなど必要な名前空間がきちんと追加されているかが重要です。

対処3:Webアプリケーション形式へ移行

もしも現在のプロジェクトがWebサイト形式である場合は、試験的にWebアプリケーション形式へ移行するのも一つの手段です。Visual Studio上で新しいWebアプリケーションプロジェクトを作り、既存のASP.NETページやクラスファイルを移植することで、より明示的なビルド・リビルドが行えます。移行する際は以下の手順が一般的です。

  1. Visual Studioで「新しいプロジェクト」を選択し、ASP.NET Webアプリケーションを作成
  2. 既存のソースファイル(ASPX, CS, Web.configなど)を順次コピー
  3. ProjectName.csprojの参照ライブラリやNuGetパッケージを同一に設定
  4. ビルドして問題がないか確認し、aspnet_compiler.exe -c等で事前コンパイルをテスト

Webアプリケーション形式ではプロジェクトファイルに明示的にコンパイル対象が定義されるため、ItemType関連のエラーが軽減されることがあります。

対処4:ItemTypeを一時的に外してみる

すぐに解決できない状況であれば、強く型付けされたデータバインディングを使わない方法に戻して動作検証を行うのもトラブルシュートの一案です。たとえば下記のようにEvalを利用したマークアップに変更して、コンパイルが通るかどうかを確認します。

<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False">
    <Columns>
        <asp:TemplateField HeaderText="名前">
            <ItemTemplate>
                <%# Eval("Name") %>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="年齢">
            <ItemTemplate>
                <%# Eval("Age") %>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

これでエラーが解消される場合、やはりItemTypeまわりの設定やコンパイラ参照がうまくいっていない可能性が高いと言えます。いずれ最終的にはItemTypeを使ったコードを正しく活かすための設定修正が必要になります。

対処5:ビルド手順の見直しとMSBuildの活用

Visual Studioのビルドや発行(Publish)機能を使う方法だけでなく、msbuild.exeやビルドスクリプトを用いて事前コンパイルを実行してみると、問題の切り分けが進む場合があります。MSBuildでの事前コンパイルを行うには、ターゲットにResolveReferencesBuildを明示し、最終的にaspnet_compiler.exeを呼び出す段取りを組むことが多いです。環境によっては、Visual Studioの「Web配置」を使うだけで問題が解消する場合もあります。

トラブルシュート時に確認しておきたいポイント

1. ターゲットフレームワークの明確化

.NET Framework 4.5~4.8は同じv4.0系ランタイムをベースにしているため、特定のコンパイラや設定ファイルが上書きされていると、自分が思っているバージョンと違うアセンブリを参照しにいく可能性があります。Visual Studioの「プロジェクトのプロパティ」やWeb.config.csprojファイルでしっかりと4.8が指定されているか見直すことが第一歩です。

2. 依存ライブラリやNuGetパッケージのバージョン確認

特にSystem.Web.dllSystem.Web.ModelBinding.dllなど、GridViewが内部で参照するアセンブリのバージョンに不整合があると、事前コンパイル時にエラーが生じます。NuGetパッケージを使用している場合はパッケージのバージョンを揃え、プロジェクト全体で一貫したバージョンになるように意識してください。

3. グローバルアセンブリキャッシュ(GAC)の影響

Windows環境では、特定のアセンブリがGAC(Global Assembly Cache)にインストールされているかどうかが動作に影響を与えることがあります。開発環境と本番サーバーで同じバージョンのアセンブリがインストールされているか、gacutilコマンドなどで確認することも効果的です。

GACのバージョン確認例

gacutil /l System.Web

このようにすると、GACに登録されているSystem.Webの一覧とバージョンが表示されます。すべての環境で同じバージョンが使われているかチェックして、怪しい場合はアップデートや再インストールを検討してください。

まとめ:強く型付けされたGridViewを使いこなすために

ItemTypeは便利な反面、プロジェクト設定やコンパイル手順が古いままだったり、Webサイト形式の動的コンパイルと相性が悪かったりすると、思わぬエラーを招きます。スムーズに開発を進めるには、以下のステップがおすすめです。

  1. まずはWeb.configや.csprojファイルでtargetFrameworkが4.8になっているか確認
  2. aspnet_compiler.exemsbuild.exeのバージョンをチェックし、正しい場所を参照させる
  3. Webアプリケーション形式への移行など、プロジェクト形態を見直す
  4. それでも解決しない場合はItemTypeを暫定的に外し、コンパイルが通るか確認
  5. 必要に応じてフォーラムやMicrosoft Q&AなどでWeb.config・マークアップを提示しつつ相談

いったんエラーが解消できれば、強く型付けされたデータバインディングの威力で、型情報を活かした開発がとても快適になります。細かな設定をすり合わせて、ASP.NET 4.8の機能を最大限活用していきましょう。

コメント

コメントする