我在控制器操作中使用MVC5和路由属性修饰。我想在Application_Error函数中使用Controller.Execute命令将调用转移到mvc但是我得到异常“在控制器'ErrorsController'上找不到公共操作方法'HttpError404'。”
如果我删除RouteAttribute装饰,一切正常,但我确实需要RouteAttribute装饰。为什么会发生这种情况?考虑到我不想使用HttpContext.Current.Server.TransferRequest
技巧,我该如何解决这个问题?
[RoutePrefix("Errors")]
public class ErrorsController : Controller
{
[Route("HttpError404")]
public ActionResult HttpError404()
{
return View();
}
}
protected void Application_Error(object sender, EventArgs e)
{
var routeData = new RouteData();
routeData.Values.Add("controller", "errors");
routeData.Values.Add("action", "HttpError404");
var requestContext = new RequestContext(new HttpContextWrapper(HttpContext.Current), routeData);
var controllerFactory = ControllerBuilder.Current.GetControllerFactory();
var controller = controllerFactory.CreateController(requestContext, "errors");
try
{
controller.Execute(requestContext);
}
catch (Exception ex)
{
//A public action method 'HttpError404' was not found on controller 'ErrorsController'.
}
}
答案 0 :(得分:0)
我重现了你的问题并得到了这个错误输出日志:
发现了System.Web.HttpException
HResult = -2147467259(0x80004005)
消息=公共行动方法' HttpError404'在控制器上找不到 ' [应用程序名] .Controllers.ErrorsController&#39 ;.
源= System.Web.Mvc
错误码= -2147467259
WebEventCode = 0
堆栈跟踪:at System.Web.Mvc.Controller.HandleUnknownAction(String actionName)
在System.Web.Mvc.Controller.ExecuteCore()
在System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext) 的RequestContext)
在[ApplicationName] .MvcApplication.Application_Error(Object sender,EventArgs e)中 [ProjectPath] \ [ApplicationName] \ [ApplicationName] \ Global.asax.cs:第XX行
通过查看上面的异常详细信息,异常来自System.Web.Mvc.Controller.HandleUnknownAction
方法,默认情况下看起来像这样(取自aspnetwebstack reference):
protected virtual void HandleUnknownAction(string actionName)
{
// If this is a direct route we might not yet have an action name
if (String.IsNullOrEmpty(actionName))
{
throw new HttpException(404, String.Format(CultureInfo.CurrentCulture, MvcResources.Controller_UnknownAction_NoActionName, GetType().FullName));
}
else
{
throw new HttpException(404, String.Format(CultureInfo.CurrentCulture, MvcResources.Controller_UnknownAction, actionName, GetType().FullName));
}
}
作为一种解决方法,请尝试通过从相应的操作方法返回视图来覆盖该方法(使用与操作方法名称相同的名称),如下例所示:
public class ErrorsController : Controller
{
// put error action methods here
protected override void HandleUnknownAction(string actionName)
{
// returns view from given action name
// better to use try-catch block just in case the view name is not exist
this.View(actionName).ExecuteResult(this.ControllerContext);
}
}
注1:如果您对操作方法名称有不同的视图名称,请使用if-condition或switch...case
阻止。
注2:标准路由可能在启用RouteAttribute
并且由于未知原因调用HandleUnknownAction
时搞砸了,我建议删除属性路由,如果相应的操作方法使用IController.Execute
调用。
参考文献: