- PR -

【ASP.NET】Server.Transfer

投稿者投稿内容
AERITH
会議室デビュー日: 2005/10/14
投稿数: 15
投稿日時: 2005-10-29 15:28
OS:XP Pro SP1
ソフト:VB.NET
言語:ASP.NET

こんにちは。
初歩的な所ですが躓いてしまったのでお知恵を拝借したく思います。

Server.Transferを使用したいのですが、記述すると

「非共有メンバを参照するには、オブジェクト参照が必要です。」

というエラーが出てしまいます。
他のServer.Transferが使用できているページと比べると、

Inherits System.Web.UI.Page

という記述がないことがわかりました。
ただ、Server.Transferを使用しようとしているメソッドを書いている所には
カスタムコントロールの設定を行うために、

Inherits System.Web.UI.WebControls.Button

という記述があるため、上記のInherits System.Web.UI.Pageの記述ができません。

そこで

Dim Server As System.Web.HttpServerUtility

という宣言を加えると、エラー(の波線)が消えてビルドできるようにはなったのですが
実際に遷移しようとカスタムボタンをクリックすると

オブジェクト参照がオブジェクト インスタンスに設定されていません。

というエラーが出て終了してしまいます。

Server.Transferを使用するための宣言の仕方が今ひとつわからなかったので
申し訳ありませんが、アドバイスを頂ければと思います。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-10-29 15:44
こんにちは。

引用:

オブジェクト参照がオブジェクト インスタンスに設定されていません。

というエラーが出て終了してしまいます。


という事なので、オブジェクト参照にインスタンスを設定してあげて下さい。

Page クラスに Server プロパティがあり、その型は HttpServerUtility だ、という所までは理解されているようですね。
その Server プロパティは誰かがインスタンスを作っているわけですよね。
で、今自分が使いたい箇所には、HttpServerUtility のインスタンスがないので、作ってあげなければなりません。
コード:
HttpServerUtility server = new HttpServerUtility();
server.Transfer("hogehoge");


これで解決…。
と言いたいところですが、HttpServerUtility はインスタンスを作る事ができません。

とりあえず、Button くらすの Page プロパティを使ってみては?

#しかし、該当のカスタムコントロールがクリックイベントを使って、親ページが遷移した方がいいような気も…。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2005-10-29 15:49
結論から書くと、

System.Web.HttpContext.Current.Server.Transfer("hogehoge")

これでいけます。

自分の書いているコードを実行すると、メモリ上にどのような状態が出来上がるのか想像しながらコードを書くといいです。
入門書などを、端折らないで一度最初から最後まで読んでみることをお勧めします。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2005-10-30 00:37
引用:

囚人さんの書き込み (2005-10-29 15:44) より:
その Server プロパティは誰かがインスタンスを作っているわけですよね。
で、今自分が使いたい箇所には、HttpServerUtility のインスタンスがないので、作ってあげなければなりません。


んー、正直、参照がないときにnewして作ろうと言う発想は危ない場合が多いので余りおすすめできません。
どういう場合は大丈夫でどういう場合はダメという判断が、何となくでもつくのであればいいんですけどね。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-10-30 11:54
引用:

んー、正直、参照がないときにnewして作ろうと言う発想は危ない場合が多いので余りおすすめできません。


いやぁ、宣言しただけで使おうとしていたので、例えで出しただけです^^;

new しただけで使用できないのは、そもそも new できない設計になっているでしょうし(今回の場合も)、new して使えるものは new できる設計になっているでしょう。

…と言いたい所ですが、なちゃんさんの仰る通り、必ずしもそうなっているとは限りませんね。
このインスタンスは「誰が」作っているのか、「何故」インスタンスが作れないのか。いろいろ試していたら、そいうのが徐々に理解できるようになると思います。
AERITH
会議室デビュー日: 2005/10/14
投稿数: 15
投稿日時: 2005-10-31 10:14
こんにちは。

囚人さん、一郎さん、なちゃさんご返答ありがとうございます。

一郎さんより教えて頂いた記述にて無事動作し、業務的には全く問題ないのですが
私自身が今ひとつ理解できないことが問題になってしまいましたので、申し訳ないですがもう少しだけお願いいたします。


--------------------------------------------------------------------------------
その Server プロパティは誰かがインスタンスを作っているわけですよね。
で、今自分が使いたい箇所には、HttpServerUtility のインスタンスがないので、作ってあげなければなりません。
--------------------------------------------------------------------------------

これはなんとか理解できました。
Serverプロパティのインスタンスを調べたところHttpServerUtilityだというのがヘルプにてわかりました。
しかし

--------------------------------------------------------------------------------
HttpServerUtility server = new HttpServerUtility()
server.Transfer("hogehoge")
--------------------------------------------------------------------------------

だと、囚人さんも言われているように"「HttpServerUtility」は宣言されていません"と表示されインスタンスを作成することができませんでした。


--------------------------------------------------------------------------------
結論から書くと、

System.Web.HttpContext.Current.Server.Transfer("hogehoge")

これでいけます。
--------------------------------------------------------------------------------

それで上記のコードを記述した所、動作いたしました。
MSDNを見てもHttpContextメンバのところに

Server:Web 要求の処理で使用されるメソッドを提供する HttpServerUtility オブジェクトを取得します。

という記載がありましたので、これを使えばHttpServerUtilityオブジェクトが使用できるとわかりました。
しかし実際こういったのはどのように調べられているのでしょうか?
答えを見れば納得いくのですが"Server.Transferを使いたいが「HttpServerUtility」はインスタンスを作成できない"となったときに取っ掛かりがないというのが現状です。
調べ方が足りないと言われればそれまでなのですが、やはり勉強を兼ねてひとつひとつどういうインスタンスがあるのかを見ていくのが近道ということでしょうか。

また

--------------------------------------------------------------------------------

んー、正直、参照がないときにnewして作ろうと言う発想は危ない場合が多いので余りおすすめできません。

--------------------------------------------------------------------------------

とありますが、これは具体的にどう危険なのでしょうか?
囚人さんが言われてますようにnewできないものは記述した段階でエラーが表示、もしくはビルドできないので
そんなことはないのではないかと思ったりしたのですが…意図を勘違いしていましたら申し訳ありません。


--------------------------------------------------------------------------------
自分の書いているコードを実行すると、メモリ上にどのような状態が出来上がるのか想像しながらコードを書くといいです。
入門書などを、端折らないで一度最初から最後まで読んでみることをお勧めします。
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
このインスタンスは「誰が」作っているのか、「何故」インスタンスが作れないのか。
いろいろ試していたら、そいうのが徐々に理解できるようになると思います。
--------------------------------------------------------------------------------

基礎も出来ていないのにご丁寧に回答して頂いてありがとうございました。
サンプルソース等を見ても「こういう風に動くんじゃないかなぁ」といった感じで漠然としか動きを理解していないのが原因でした。
今一度、ソースを見直してみようと思います。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2005-10-31 11:21
引用:

AERITHさんの書き込み (2005-10-31 10:14) より:
------------------------------------------------------------------
んー、正直、参照がないときにnewして作ろうと言う発想は危ない場合が多いので余りおすすめできません。
------------------------------------------------------------------
とありますが、これは具体的にどう危険なのでしょうか?


オブジェクトのメソッドは、C言語の関数やVBの標準モジュールのプロシージャなどと違ってそのメソッドが属するオブジェクトの状態により動作が変わります。
コード:

Private Sub F()
Dim arr As ArrayList = New ArrayList
G()
End Sub

Private Sub G()
Dim a As ArrayList = New ArrayList
arr.Add("aaa")
End Sub


ArrayListのAdd()メソッドは"ArrayListに項目を追加"という仕事をするといっても、G()内のAdd()呼び出しではF()内で定義されているarrには項目を追加できませんよね。
極端に書きましたが、"HttpServerUtility.Transfer()は画面の遷移をするから"とnewして使うのとやっていることは同じです。

[ メッセージ編集済み 編集者: 一郎 編集日時 2005-10-31 11:26 ]
AERITH
会議室デビュー日: 2005/10/14
投稿数: 15
投稿日時: 2005-10-31 19:51
こんにちは。

一郎さん、ご返信ありがとうございます。

…なのですが今ひとつ理解できませんでした(泣
前半のArrayListに関しての例は理解できたのですが、最後の
「"HttpServerUtility.Transfer()は画面の遷移をするから"とnewして使うのとやっていることは同じです。」
でこんがらがってしまいました。
この2つのメソッドは役割が違うので、newしたものと同じこと…ということでしょうか。

HttpServerUtility.Transfer()とnew HttpServerUtility()(←?)は同じであるけれども、
newを使うのが危ないというのがしっくり来ませんでした。
同じなら大丈夫なのでは?と単純に考えてしまいまして…ううぅ、すみませんm(_ _)m





…とその上、追加の質問で申し訳ないですがお願いいたします。

上記のServer.Transferメソッドを使用していたのですが
try〜catchの中に入れるとThreadAbortExceptionが発生してしまい、必ずcatchを通るようになってしまいました。
調べてみた所、try〜catchの中ではServer.Transferは使えないらしく、
Response.Redirect("xxxx.aspx", false)
にて対処せよ、とのことでした。

しかしこの方法ですとURLに直接アクセスすることになるので
もし存在しないページにアクセスした場合(現在、遷移先ページはclickイベントに引数にして持たせています)、
Server.Transferだと遷移前のページの処理中に遷移先のPage_Loadが(?)走るため、catchを通ってくれていたのが
Response.Redirectだとend tryに行ってから遷移するため、エラーが表示されて終わってしまいます。
(存在しないページにアクセスしようとした場合には既定のページに飛ばす、という処理がしたいためです)

Microsoftのサポートを見たところ、「Server.Transfer の場合は、代わりに Server.Execute メソッドを使用します。」
とありますが、これだと当然遷移前のページの内容の上に遷移先のページが被ってしまうのでどうしたらいいかと思っている所です。
(遷移する前に遷移元のフォーム内容をクリアする……とかでしょうか)

もし何か対処法をご存知でしたらお願いしたく思います。

スキルアップ/キャリアアップ(JOB@IT)