代码之家  ›  专栏  ›  技术社区  ›  Stefanvds

MVC使用动作过滤器检查URL中的参数。停止执行操作

  •  4
  • Stefanvds  · 技术社区  · 14 年前

    我想做以下事情:

    当URL没有instid时,我想重定向到 "Instelling" 行动

    在这 控制器 ,每个方法都需要instid。

            [RequiredParameter(parameterName="instID", controllerToSend="Instelling")]
            public ActionResult Index(int? instID) {
                //if (!instID.HasValue) {
                //    return RedirectToAction("Index", "Instelling");
                //}
    
                var facts = _db.Instellingens.First(q => q.Inst_ID == instID).FacturatieGegevens;
    
                return View(facts);
            }
    

    所以这是在控制器中。

    操作过滤器:

    namespace MVC2_NASTEST.Controllers {
        public class RequiredParameterAttribute : ActionFilterAttribute {
    
            public string parameterName { get; set; }
            public string actionToSend { get; set; }
            public string controllerToSend { get; set; }
    
            public override void OnActionExecuting(ActionExecutingContext filterContext) {
    
                if (parameterName != string.Empty) {
                    if (filterContext.ActionParameters.ContainsKey(parameterName) && filterContext.ActionParameters[parameterName] != null) {
                        string s = "test";
                        //all is good
                    } else {
                        //de parameter ontbreekt. kijk of de controller en de action geset zijn.
                        if (actionToSend == string.Empty)
                            actionToSend = "Index";
                        if (controllerToSend == string.Empty) {
                            controllerToSend = filterContext.Controller.ToString();
                            controllerToSend = controllerToSend.Substring(controllerToSend.LastIndexOf(".") + 1);
                            controllerToSend = controllerToSend.Substring(0, controllerToSend.LastIndexOf("Controller"));
                        }
    
                        UrlHelper helper = new UrlHelper(filterContext.RequestContext);
                        string url = helper.Action(actionToSend, controllerToSend);
    
                        HttpContext.Current.Response.Redirect(url);
                        //filterContext.HttpContext.Response.Redirect(url, true);
                    }
                }
    
                base.OnActionExecuting(filterContext);
            }
    
            public override void OnActionExecuted(ActionExecutedContext filterContext) {
    
    
                base.OnActionExecuted(filterContext);
            }
    
        }
    }
    

    问题是:它确实有效,但是,操作本身首先被执行,然后重定向就发生了。这不是我想要的。

    也许我不应该使用actionfilters,而应该添加一个路由? 在这种情况下,如果instid丢失,如何将路由重定向到另一个控制器?

    2 回复  |  直到 10 年前
        1
  •  7
  •   Clicktricity    14 年前

    与其创建操作筛选器(在返回操作方法之前运行),还不如考虑更改为授权筛选器,该筛选器允许您重定向到其他控制器和操作

    类似这样(伪代码):

    public class RequiredParameterAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            // read instID from QueryString
            // if instId is null, return false, otherwise true
        }
    
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.result = new RedirectToRouteResult( new { controller = "MyController" , action = "MyAction" }  )
        }
    

    }

        2
  •  2
  •   Evan Bosscher    10 年前

    这是我在谷歌上问的一个问题的第一个结果,所以我想提出一个不同的答案。不是从操作中执行重定向,而是分配一个重定向到FilterContext。结果如下:

    filterContext.Result = new RedirectResult(url);
    

    如果filterContext的result属性不为空,则不会执行基础操作。因为您在调用上下文之外执行重定向,所以仍将执行action方法。