2016-02-19 59 views
0

该标题有误导性,但我不确定如何更好地说出它。我的BaseController可以有一个方法返回一个重定向或true?

我的控制器全部继承自BaseController。我想在BaseController中有一个方法,我可以从各种操作中调用。我想是这样的:

public virtual object CheckValues(Guid value1, string value2) 
{ 
    if (value2 == const_SomeValue || value1 == GetCurrentId()) 
    { 
     return true; 
    } 
    return RedirectToAction("index"); 
} 

基本上,我想寿有将检查某些事情的方法,如果失败,做一个重定向。我的控制器行动将检查它是这样的:

public virtual ActionResult overview(Guid? id) 
{ 
    CheckValues(id, string.Empty); // on fail this redirects 

    // Continue with this Action 
    return View(); 
} 

我的许多控制器行动将利用CheckValues方法。

有没有一个好的或正确的方法来做到这一点?

更新:我想分享我的解决方案。我喜欢它是如何出来的。

我现在控制器可以是这样的:

[CheckId()] // I can overload the name of the Id, the redirect Action and/or contoller 
public virtual ActionResult overview(Guid? id) 
{ 
    //... Logic for my action 
    return View(); 
} 

我的过滤器看起来是这样的:

public class CheckIdAttribute : ActionFilterAttribute 
{ 
    public string IdValue { get; set; } 
    public string RedirectAction { get; set; } 
    public string RedirectController { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     // I wanted to be able to override the redirect and 
     // the name of the id to check if necessary. Or just 
     // use defaults. 
     if (string.IsNullOrEmpty(IdValue)) 
      IdValue = "id"; 

     if (string.IsNullOrEmpty(RedirectAction)) 
      RedirectAction = "index"; 

     if (string.IsNullOrEmpty(RedirectController)) 
      RedirectController = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; 

     var isValue1Valid = filterContext.ActionParameters.ContainsKey(IdValue) && 
      (filterContext.ActionParameters[IdValue] != null && (Guid)filterContext.ActionParameters[IdValue] != Guid.Empty); 

     if (!isValue1Valid) 
     { 
      filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { action = RedirectAction, controller = RedirectController })); 
     } 
    } 
} 
+1

可能有一个操作返回一个BaseController中的操作,该操作将用户发送到与您正在使用的控制器相关的视图。但是将RedirectToAction作为对象返回是讨厌的;为什么不在基地做两件事。一个返回一个布尔值,并根据跳转到您的控制器重定向的结果。 – MartijnK

+0

嗯...好主意。我不喜欢我的想法。我喜欢干净和基于模式。 –

+1

或者,将bool返回函数移到别的地方(不同的类或服务,远离控制器),只留下BaseController中的Action。这将进一步清理您的控制器并保持整洁。 :) – MartijnK

回答

3

基类方法的替代方法是行动的过滤器。你的控制器动作看起来是这样的:

[CheckValues(Value1 = "id", Value2 = "")] 
public ActionResult overview(Guid? id) 
{ 
    // Continue with this Action 
    return View(); 
} 

然后在操作过滤器,覆盖OnActionExecuting检查参数,并可能重定向。

public class CheckValuesAttribute : ActionFilterAttribute 
{ 
    public string Value1 { get; set; } 
    public string Value2 { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
    var isValue2Valid = filterContext.ActionParameters.ContainsKey(Value2) && 
         filterContext.ActionParameters[Value2] == const_SomeValue; 
    var isValue1Valid = filterContext.ActionParameters.ContainsKey(Value1) && 
         filterContext.ActionParameters[Value1] == GetCurrentId(); 

    if (!isValue1Valid || !isValue2Valid) 
     filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { action = "Index"})); 
    } 
} 

以上仍然需要一些调整来应对时Value2缺失/空字符串和铸造Value1为GUID的情况,但这是它的要点。您设置filterContext.Result的行可能会使您的操作短路,从而实际上从未执行 - 重定向会在请求发生之前发生,然后再发送到您的控制器操作。

+0

我知道我曾见过类似的东西,但不记得名字。谢谢。研究。 –

+0

干净整洁的解决方案。 – MartijnK

+0

还有一个问题。有没有办法在过滤器中获得Request.Url.AbsolutePath? –

相关问题