无法在OnActionExecuting中从其他控制器返回视图

时间:2014-04-25 16:26:50

标签: c# asp.net-mvc

我正在创建一个单页面应用程序。我有一个名为ControllerBase的抽象类,我的所有控制器都从它继承。

我有一个名为' Application'的控制器,其中包含一个名为' Container'的操作。该视图包含应用程序视图。

我希望它工作的方式是:如果请求是AJAX,则从控制器返回ActionResult。如果请求不是AJAX,请致电'应用程序'控制器并呈现动作'容器'发送路由数据,以便客户端负责进行AJAX调用以构建页面。

这是控制器基础。

public class ControllerBase : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var request = filterContext.HttpContext.Request;

        // If the request is AJAX, let it go through
        if (request.Headers["X-Requested-With"].IsEqualTo("xmlhttprequest"))
        {
            base.OnActionExecuting(filterContext);
        }
        // If the request is not AJAX, then the response needs to be modified.
        else
        {
            // This is the controller that contains the single-page application view.
            var applicationController = new ApplicationController();
            applicationController.ControllerContext = 
                new ControllerContext(ControllerContext.RequestContext, applicationController);        

            // Render the single page application and let it take care of the result
            filterContext.Result = applicationController
                .Container(filterContext.RouteData.Values["Controller"].ToString(),
                    filterContext.RouteData.Values["Action"].ToString(), null);
        }
    }
}

这是应用程序控制器。

public class ApplicationController : ControllerBase
{
    public ActionResult Container(string controller, string action, string id)
    {
        if (controller.IsEqualTo("application")) controller = null;
        if (action.IsEqualTo("container")) action = null;
        return View(new RequestModel(controller, action, id));
    }
}

以下是任何其他控制器,如果它不是AJAX,必须通过Application控制器捕获并呈现对它的任何请求。

public class BusinessController : ControllerBase
{
    public ActionResult Index()
    {
        return View();
    }
}

当我路由到以下路线时:/ Business / Index,OnActionExecuting规则工作正常,但出来的视图不会呈现' Container'看来,它呈现了'指数'视图。我无法弄清楚我做错了什么。

1 个答案:

答案 0 :(得分:1)

呈现错误视图的原因是因为过滤器上下文未指向正确的控制器和操作。

这是固定的OnActionExecuting方法。

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var request = filterContext.HttpContext.Request;

    // If the request is AJAX, let it go through
    if (request.Headers["X-Requested-With"].IsEqualTo("xmlhttprequest"))
    {
        base.OnActionExecuting(filterContext);
    }
    // If the request is not AJAX, then the response needs to be modified.
    else
    {
        // Get original values of controller and action data
        var controllerName = filterContext.RouteData.Values["Controller"].ToString();
        var actionName = filterContext.RouteData.Values["Action"].ToString();

        // Set new values so that the view engine knows what view to render
        filterContext.RouteData.Values["Controller"] = "Application";
        filterContext.RouteData.Values["Action"] = "Container";

        // This is the controller that contains the single-page application view.
        var applicationController = new ApplicationController();
        applicationController.ControllerContext = 
            new ControllerContext(ControllerContext.RequestContext, applicationController);

        // Render the single page application and let it take care of the result
        filterContext.Result = applicationController.Container(controllerName, actionName, null);
    }
}

现在我的所有控制器都将路由到一个页面,而该单页将处理所有请求。