更改 ASP.NET MVC 筛选器中的视图

发布于 2024-11-10 11:33:12 字数 1044 浏览 0 评论 0原文

如果用户使用移动浏览器,我想将用户重定向到不同的视图。我决定使用 MVC 过滤器来完成此操作,将其应用于我想要具有移动视图的操作。

我相信这个重定向需要在 OnActionExecuted 中发生,但是 filterContext 不包含视图上的信息 - 它包含在 OnResultExecuted 中,但此时我认为更改视图为时已晚。

如何拦截视图名称并更改 ViewResult?

这就是我在执行结果中得到的内容以及我希望在执行操作中进行的工作。

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);
    }
}

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);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷了相思 2024-11-17 11:33:12

我会向您推荐以下博客文章,它解释了实现您所要求的更好的替代方案for 而不是使用动作过滤器。

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.

伤痕我心 2024-11-17 11:33:12

这就是我最终所做的,并包装成一个可重用的属性,最棒的是它在根据您的要求重定向(或应用您想要的任何结果)时保留原始 URL:

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";
    }
}

然后只需添加属性 [SiteAccessAuthorise ] 添加到您希望应用授权访问的控制器(在我的例子中)或将其添加到 BaseController。确保您重定向到的底层控制器的操作没有该属性,否则您将陷入无限循环!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文