[PRB] Server.Transfer を使用するとエラー メッセージ "ViewState は無効です" が表示される

サポートが終了した KB の内容についての免責事項

この記事は、マイクロソフトがサポートを提供しなくなった製品について記述しています。 したがって、この記事は「現状のまま」で提供され、更新されることはありません。

現象

HttpServerUtility.Transfer("page name", true) を使用すると、以下のエラー メッセージが表示されます。
このページの ViewState は無効です。壊れている可能性があります。

原因

この問題は、<pages> 要素の EnableViewStateMac 属性がデフォルトで true に設定されているために発生します。この属性が true に設定されている場合、クライアントからページが返送されると、ASP.NET がそのページのビュー ステートに対してメッセージ認証チェック (MAC) を実行します。このチェックでは、ページのビュー ステートがクライアント上で修正されたかどうかが確認されます。セキュリティ上の理由から、この属性は true に設定しておくことをお勧めします。


Server.Transfer メソッドを呼び出して 2 番目のパラメータを true に設定すると、QueryString コレクションおよび Form コレクションが保持されます。フォーム フィールドの 1 つが非表示の __VIEWSTATE フォーム フィールドになり、そのページのビュー ステートを保持します。メッセージ認証チェックでは各ページがチェックされるだけであるため、ビュー ステートのメッセージ認証チェックは失敗します。このため、Server.Transfer を呼び出すページのビュー ステートが転送先のページで無効になります。


ビュー ステートはページ限定で、そのページに対してのみ有効です。ビュー ステートをページ間で転送しないでください。

解決方法

この問題を解決するには、次のいずれかの方法を使用します。

解決策 1

ページ間で値を転送し、サーバー コントロール値を他のページに渡します。詳細については、以下の MSDN ドキュメントを参照してください。
この場合、転送先ページからアクセスするコントロールの各プロパティに対してパブリック プロパティを作成する必要があります。


コントロールが多数あり、コントロールのプロパティに別のページからアクセスする場合は、コントロールをパブリック変数として宣言することもできます。以下に例を示します。


Page1.aspx
Public Class Page1
Public WithEvents TextBox1 As System.Web.UI.WebControls.TextBox
'Insert your code here.
End Class
Page2.aspx
            Dim sourcePage As Page1
sourcePage = CType(Context.Handler, WebForm1)
Response.Write(sourcePage.TextBox1.Text)

解決策 2

Server.Transfer を呼び出す場合は、2 番目のパラメータ (デフォルトでは false) を渡さないようにします。以下に例を示します。
Server.Transfer("<page name>")
上記のコードでは、呼び出されるページに QueryString フィールドおよび Form フィールドを送信しません。データが転送されないので、ASP.NET はメッセージ認証チェックを実行しません。

詳細

問題の再現手順

  1. 別のページに実行を転送する WebForm1.aspx という名前の .aspx ページを作成します。WebForm1.aspx に以下のコードを追加します。
    <%@ Page language="vb" AutoEventWireup="true" %>
    <html>
    <body>
    <form id="WebForm1" method="post" runat="server">
    <asp:TextBox id="txtName" runat="server">Your Name</asp:TextBox><br>
    <asp:Button id="Button1" runat="server" Text="Submit" OnClick="Button1_Click"></asp:Button>
    </form>
    </body>
    </html>
    <script runat=server>
    Sub Button1_Click(sender As Object, e As System.EventArgs)
    Server.Transfer("WebForm2.aspx",true)
    End Sub
    </script>
  2. WebForm2.aspx という名前の別の .aspx ページを作成し、以下のコードを追加します。
    <%@ Page language="vb" AutoEventWireup="true" %>
    <html>
    <body>
    <form id="WebForm2" method="post" runat="server">
    <asp:Label id="lblName" runat="server" >Web Form 2</asp:Label>
    </form>

    </body>
    </html>
    <script runat=server>
    Sub Page_Load(sender As Object, e As EventArgs)
    Dim thisPage As System.Web.UI.Page
    Dim nameTextBox As TextBox
    thisPage = CType(Context.Handler, System.Web.UI.Page)
    nameTextBox = CType(thisPage.FindControl("txtName"), System.Web.UI.Control)
    lblName.Text = "Your name is '" & nameTextBox.Text & "'."

    End Sub
    </script>
  3. ブラウザで WebForm1.aspx を開き、[Submit] をクリックします。

関連情報

この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 316920 (最終更新日 2004-01-20) を基に作成したものです。


この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。
プロパティ

文書番号:316920 - 最終更新日: 2008/07/14 - リビジョン: 1

フィードバック