Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing the view in an ASP.NET MVC Filter

I want to redirect the user to a different view if they are using a mobile browser. I've decided I'd like to do this using MVC filters by applying it to actions which I want to have a mobile view.

I believe this redirect needs to happen in OnActionExecuted, however the filterContext does not contain information on the view - it does, however in OnResultExecuted, but by this time I believe it is too late to change the view.

How can I intercept the view name and change the ViewResult?

This is what I have in the result executed and what I'd like to have work in Action Executed.

public class MobilePageFilter : ActionFilterAttribute
{
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if(filterContext.Result is ViewResult)
        {
            if (isMobileSite(filterContext.HttpContext.Session[SetMobile.SESSION_USE_MOBILE]))
            {
                ViewResult viewResult = (ViewResult)filterContext.Result;

                string viewName = viewResult.ViewName;
                filterContext.Result = new ViewResult
                {
                    ViewName = "Mobile/" + viewName,
                    ViewData = viewResult.ViewData,
                    TempData = viewResult.TempData
                };
            }
        }

        base.OnResultExecuted(filterContext);
    }
}
like image 292
Sam Avatar asked May 30 '11 13:05

Sam


People also ask

Can we override filters in MVC?

ASP.NET MVC 5 has arrived with a very important feature called Filter Overrides. Using the Filter Overrides feature, we can exclude a specific action method or controller from the global filter or controller level filter. ASP.NET MVC 5 has arrived with a very important feature called Filter Overrides.

Can you specify different types of filters in ASP.NET MVC application?

The ASP.NET MVC framework supports four different types of filters: Authorization filters – Implements the IAuthorizationFilter attribute. Action filters – Implements the IActionFilter attribute. Result filters – Implements the IResultFilter attribute.


2 Answers

I would recommend you the following blog post which explains a better alternative to achieve what you are asking for rather than using action filters.

like image 78
Darin Dimitrov Avatar answered Sep 23 '22 02:09

Darin Dimitrov


This is what I ended up doing, and wrapped up into a reusable attribute and the great thing is it retains the original URL while redirecting (or applying whatever result you wish) based on your requirements:

public class AuthoriseSiteAccessAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        // Perform your condition, or straight result assignment here.
        // For me I had to test the existance of a cookie.
        if (yourConditionHere)
            filterContext.Result = new SiteAccessDeniedResult();
    }

}

public class SiteAccessDeniedResult : ViewResult
{
    public SiteAccessDeniedResult()
    {
        ViewName = "~/Views/SiteAccess/Login.cshtml";
    }
}

Then just add the attribute [SiteAccessAuthorise] to your controllers you wish to apply the authorisation access to (in my case) or add it to a BaseController. Make sure though the action you are redirecting to's underlying controller does not have the attribute though, or you'll be caught in an endless loop!

like image 41
GONeale Avatar answered Sep 21 '22 02:09

GONeale