New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNN-10507: MVC ActionFilter Now Supports Redirects #1931

Merged
merged 5 commits into from Jan 10, 2018

Conversation

Projects
None yet
3 participants
@ahoefling
Contributor

ahoefling commented Nov 14, 2017

Adds support for ActionFilter redirects inside the DNN MVC Framework.

  • Redirects the action based on an ActionFilter by setting the filterContext.Result equal to an ActionResult.
  • Handles Exception Filter Redirects
    • As long as you specify filterContext.ExceptionHandled = true
  • Handles OnExecuted ActionFilter redirects
  • Handles ONExecuting ActionFilter redirects

Usage
When you define your ActionFilter you need to set the filterContext.Result property just like you would in ASP.NET MVC development. The new code in this Pull Request then takes that Result object and sets it to the View where appropriate.

If you are setting the filterContext.Result from an exception it is critical that you flip the filterContext.ExceptionHandled bit or the view won't render correctly

My Use Case
In my use case I want to display a special DNN MVC Module Error Page to the user when we have an exception thrown from the current controller where our controller has the filter RedirectOnExceptionAttribute. See code snippets below for usage of this use case

RedirectOnExceptionAttribute.cs:

[AttributeUsage(AttributeTargets.Class)]
public class RedirectOnExceptionAttribute : ActionFilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        var controller = (IHasFilterActionMethods)filterContext.Controller;
        filterContext.Result = controller.RedirectToErrorPage();
    }
}

IHasFilterActionMethods.cs:

public interface IHasFilterActionMethods
{
    ActionResult RedirectToErrorPage();
}

FooController.cs:

[RedirectOnException]
public class FooController : DnnController, IHasFilterActionMethods
{
    public ActionResult RedirectToErrorPage()
    {
        return Redirect(Url.Action(nameof(ErrorPage)));
    }

    public ActionResult ErrorPage()
    {
        return View();
    }

    public ActionResult Index()
    {
        return View();
    }
}

OnExecuted and OnExecuting Use Case
The other supported redirects in this change handle setting the filterContext.Result for both overrides in ActionFilterAttribute

  • OnActionExecuted(ActionExecutedContext filterContext)
  • OnActionExecuting(ActionExecutingContext filterContext)

The usage in this use case is the same as above. All you need to do is set the filterContext.Result in your approprate method in the ActionFilter and then the invoker will automatically handle displaying the view.

If you want to handle an exception in the OnActionExecuted you will still need to flip the ExceptionHandled bit as mentioned above for the exception use case.

@ahoefling

This comment has been minimized.

Contributor

ahoefling commented Dec 15, 2017

Any update on this?

@galatrash

@ahoefling , everything looks good except the ResultOfLastInvoke setter must be private to prevent other code from changing it accidentally or intentionally.

@@ -19,20 +19,33 @@
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Web.Mvc;
namespace DotNetNuke.Web.Mvc.Framework.Modules
{
public class ResultCapturingActionInvoker : ControllerActionInvoker
{
public ActionResult ResultOfLastInvoke { get; set; }

This comment has been minimized.

@galatrash

galatrash Jan 10, 2018

Contributor

Must change to private setter; i.e.

    public ActionResult ResultOfLastInvoke { get; private set; }

Never mind. This code is a very old code that was not changed in this PR.

@galatrash galatrash merged commit 41b2655 into dnnsoftware:development Jan 10, 2018

@galatrash galatrash added Merged and removed Awaiting Response labels Jan 10, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment