奇妙な問題に遭遇しました。私はそれを修正しましたが、実際に何が問題だったのかをよりよく理解するのを手伝ってくれることを願っています. 何が起こったのかの説明から始めます。問題は単純な MVC3 RC1 アプリに関するものです。
私のアプリのマスター ページには、ログイン フォームをレンダリングするためのコントローラーのアクションへの呼び出しがあります。
@Html.Action("LoginForm", "Account")
AccountController クラスのアクション メソッドは、ログイン フォームを含む PartialViewResult を返します。
public PartialViewResult LoginForm()
{
return PartialView();
}
今日、私はこのアクション メソッドに変更を加え、次のように HttpGetAttribute に関連付けました。
[HttpGet]
public PartialViewResult LoginForm()
{
return PartialView();
}
これが問題の原因です。ただし、問題は 1 つの特定のシナリオでのみ存在しました。これが私を困惑させます。フォームをコントローラーに投稿するとき、コントローラーのアクションがRedirectToRouteResultを返した場合、すべてが正常に機能します。アクションがViewResultを (既定のビューに) 返しただけの場合、Http404 エラー処理が開始され、永久にループします。
この質問に対する 3 番目の回答であるRequirements for 404で説明されている方法と非常によく似た方法で 404 エラー処理を実装しました。その投稿を読みたくない場合は、簡単に言えば、基本コントローラー クラスで HandleUnknownAction メソッドをオーバーライドし、そのメソッドで、ErrorController クラスのインスタンスをインスタンス化し、それに対して Execute を呼び出して、RouteData のインスタンスを渡します。
protected override void HandleUnknownAction(string actionName)
{
// If controller is ErrorController dont 'nest' exceptions
if (this.GetType() != typeof(ErrorController))
this.InvokeHttp404(HttpContext);
}
public ActionResult InvokeHttp404(HttpContextBase httpContext)
{
IController errorController = DependencyResolver.Current.GetService<ErrorController>();
var errorRoute = new RouteData();
errorRoute.Values.Add("controller", "Error");
errorRoute.Values.Add("action", "Http404");
errorRoute.Values.Add("url", httpContext.Request.Url.OriginalString);
errorController.Execute(new RequestContext(httpContext, errorRoute));
return new EmptyResult();
}
ErrorController が行うことは、エラーをログに記録し、分かりやすいエラー メッセージを含むビューを返すことだけです。まあ、それはそれがどのように機能するべきかです。しかし、この場合、エラー処理は無限ループに入り、AccountController (私のフォームが投稿された) が HandleUnknownAction を何度も何度も呼び出します。
エラー ログには、何が問題なのかを示すものは何もありませんでした (ほぼすべてをログに記録していると思います)。これも奇妙でした。したがって、コントローラーの基本クラスから HandleUnknownAction メソッドを削除すると、他の何かが明らかになる可能性があると考えました。そしてそうだった:
2010-12-10 19:11:47,956 [4] エラー Infrastructure.Log4NetAuditor [System.Web.HttpException (0x80004005): ハンドラー 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper' の子要求の実行中にエラーが発生しました。---> System.Web.HttpException (0x80004005): 子リクエストの実行に失敗しました。詳細については、InnerException を調べてください。---> System.Web.HttpException (0x80004005): コントローラー 'Cdo.Web.Controllers.AccountController' でパブリック アクション メソッド 'LoginForm' が見つかりませんでした。
何?これを見たとき、このメソッドに HttpGetAttribute を配置したことを思い出したので、すぐに削除しました...そして順序が復元されました。何が原因だったのかを突き止められたことをうれしく思いますが、なぜそれが起こったのかは不明のままです。あなたが私がこれに光を当てるのを手伝うことができれば、私は大いに感謝しています. ここで HttpGetAttribute が違いを生むのはなぜですか?