Я только что столкнулся со странной проблемой. Я исправил это, но я надеюсь, что вы сможете помочь мне лучше понять, что на самом деле пошло не так. Я начну с объяснения того, что случилось. Проблема касается простого приложения MVC3 RC1.
На главной странице моего приложения есть вызов действия на контроллере для отображения формы входа:
@Html.Action("LoginForm", "Account")
Метод действия в классе AccountController возвращает PartialViewResult, содержащий форму входа.
public PartialViewResult LoginForm()
{
return PartialView();
}
Сегодня я внес изменение в этот метод действия и связал его с атрибутом HttpGetAttribute следующим образом:
[HttpGet]
public PartialViewResult LoginForm()
{
return PartialView();
}
Вот что вызвало проблемы. Однако проблемы существовали только в одном конкретном сценарии - и это меня смущает. Когда отправляет форму в контроллер, все будет работать нормально, при условии, что действие контроллера вернуло RedirectToRouteResult . Если действие только что вернуло ViewResult (к его виду по умолчанию), моя обработка ошибок Http404 включилась бы и зациклилась бы навсегда.
Я реализовал обработку ошибок 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): Метод открытого действия 'LoginForm' не найден в контроллере 'Cdo.Web.Controllers.AccountController'.
Что за? Когда я увидел это, я вспомнил, что я добавил HttpGetAttribute в этот метод - поэтому я быстро удалил его ... и порядок был восстановлен. Я рад, что обнаружил, что вызвало это - но я остаюсь в темноте , почему это произошло. Если вы сможете помочь мне пролить некоторый свет на это, я был бы очень благодарен. Почему HttpGetAttribute имеет значение здесь?