Glenn Pavel
Glenn Pavel

Reputation: 101

How to redirect from ActionFilter to another action or route in Asp.net Core 2.2?

How can I redirect from ActionFilter to another controller/action in Asp.net Core 2.2

context.ExceptionHandled; //is not show

I have try all options on these threads:

this is my code

public class ValidaEmpresaActionFilter : IActionFilter
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly IHttpContextAccessor _contextAccessor;

    public ValidaEmpresaActionFilter(UserManager<ApplicationUser> userManager, IHttpContextAccessor contextAccessor)
    {
        _userManager = userManager;
        _contextAccessor = contextAccessor; 
    }

    public async void OnActionExecuting(ActionExecutingContext context)
    {
        string username = _contextAccessor.HttpContext.User.Identity.Name;
        var user = await  _userManager.FindByNameAsync(username);

        // all options i tried Option 1
        if (user.EmpresaPrincipal == null || user.EmpresaPrincipal < 1)
        {

            RouteValueDictionary redirectTargetDictionary = new RouteValueDictionary();
            redirectTargetDictionary.Add("action", "Index");
            redirectTargetDictionary.Add("controller", "Home");

            context.Result = new RedirectToRouteResult(redirectTargetDictionary);
        }
        // option #2
        if (user.EmpresaPrincipal == null || user.EmpresaPrincipal < 1)
            context.Result = new RedirectResult("~/Home/index");
       
        // option #3
        if (user.EmpresaPrincipal == null || user.EmpresaPrincipal < 1)
        {
            context.Result = new RedirectToRouteResult(
            new RouteValueDictionary
            {
                { "controller", "Home" },
                { "action", "Index" }
            });
        }
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
    
    }
}

in Startup/ConfigureServices

services.AddScoped<ValidaEmpresaActionFilter>();

Update: I found the answer

just added this line await context.Result.ExecuteResultAsync(context);

this is the result code:

public async void OnActionExecuting(ActionExecutingContext context)
{
    string username = _contextAccessor.HttpContext.User.Identity.Name;
    var user = await  _userManager.FindByNameAsync(username);

    if (user.EmpresaPrincipal == null || user.EmpresaPrincipal < 1)
    {
        RouteValueDictionary redirectTargetDictionary = new RouteValueDictionary();
        redirectTargetDictionary.Add("action", "Index");
        redirectTargetDictionary.Add("controller", "Home");
        redirectTargetDictionary.Add("area", "");

        context.Result = new RedirectToRouteResult(redirectTargetDictionary);
        await context.Result.ExecuteResultAsync(context);
    }             
}       

Upvotes: 9

Views: 3913

Answers (1)

Peyman Majidi
Peyman Majidi

Reputation: 1985

Hear I make [MyAuth] Action filter, if authentication passed continue else redirect to "access denied" page

    public class MyAuth : ActionFilterAttribute
    {

        public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var headers = context.HttpContext.Request.Headers;
            if(headers.ContainsKey("Authentication"))
            {
                var value = AuthenticationHeaderValue.Parse(headers["Authentication"]);
                var bytes = Convert.FromBase64String(value.Parameter);
                var crendentials = Encoding.UTF8.GetString(bytes).Split(":");
                var username = crendentials[0];
                var password = crendentials[1];
                
                if(Validate(username, password))
                {
                    // user is valid, huuuray
                    base.OnActionExecutionAsync(context, next);
                    return;

                }

            }
            // should redirect to somewhere
            context.Result = new RedirectResult("~/api/access_deny");
            await context.Result.ExecuteResultAsync(context);

        }
    }

Please attention to add this line:

            await context.Result.ExecuteResultAsync(context);

Somewhere in my Api controller before any action need my custom [MyAuth]:

...
        // GET: api/<ValuesController>
        [HttpGet]
        [MyAuth]     // <-------------------
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2", "value3" };
        }
...

Upvotes: 2

Related Questions