使用具有属性路由功能的mvc5 Controller.Execute导致异常

时间:2018-02-16 17:02:51

标签: asp.net-mvc

我在控制器操作中使用MVC5和路由属性修饰。我想在Application_Error函数中使用Controller.Execute命令将调用转移到mvc但是我得到异常“在控制器'ErrorsController'上找不到公共操作方法'HttpError404'。”

如果我删除RouteAttribute装饰,一切正常,但我确实需要RouteAttribute装饰。为什么会发生这种情况?考虑到我不想使用HttpContext.Current.Server.TransferRequest技巧,我该如何解决这个问题?

ErrorsController

[RoutePrefix("Errors")]
public class ErrorsController : Controller
{
    [Route("HttpError404")]
    public ActionResult HttpError404()
    {
        return View();
    }
}

的Application_Error

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'.           
    }
}

1 个答案:

答案 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调用。

参考文献:

MVC 5 Attribute Routing not Working with Controller Execute

Handling Unknown Actions in ASP.NET MVC