Change the view's path on the fly

2019-08-04 12:56发布

问题:

I have this class:

public abstract class MyController : Controller
{
  protected override void OnActionExecuting(ActionExecutingContext filterContext)
  {
      string viewPath = filterContext/*... .ViewPath*/;
      viewPath = "Some new View Path";
  }
}

And I'd like to retrieve and replace the executing view's path by another one. I have tried to debug-view the filter context on a web call, however I did not manage to find a view which is about to render.

How do I do that?

回答1:

From MSDN:

Controller.OnActionExecuting Method: Called before the action method is invoked. At this stage, no ActionResult exists since the Action didn't execute yet.

You better use the OnResultExecuting instead:

protected override void OnResultExecuting(ResultExecutingContext filterContext)
{
    var viewResult = filterContext.Result as ViewResult;

    if (viewResult != null)
    {
        var razorEngine = viewResult.ViewEngineCollection.OfType<RazorViewEngine>().Single();
        var viewName = !String.IsNullOrEmpty(viewResult.ViewName) ? viewResult.ViewName : filterContext.RouteData.Values["action"].ToString();
        var razorView = razorEngine.FindView(filterContext.Controller.ControllerContext, viewName, viewResult.MasterName, false).View as RazorView;
        var currentPath = razorView.ViewPath;
        var newPath = currentPath.Replace("..", "...");
        viewResult.View = new RazorView(filterContext.Controller.ControllerContext, newPath, razorView.LayoutPath, razorView.RunViewStartPages, razorView.ViewStartFileExtensions);
    }

    base.OnResultExecuting(filterContext);
}