【问题标题】:Can my BaseController have a method return a redirect or true?我的 BaseController 可以有一个方法返回重定向或 true 吗?
【发布时间】:2016-02-19 23:51:14
【问题描述】:

该标题具有误导性,但我不知道如何更好地表达它。

我的控制器都继承自 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 }));
        }
    }
}

【问题讨论】:

  • 在 BaseController 中可能有一个返回动作的动作,它将用户发送到与您正在使用的控制器相关的视图。但是将 RedirectToAction 作为对象返回是令人讨厌的;为什么不在基地做两个动作。一个返回布尔值,并根据从控制器跳转到重定向的结果。
  • 嗯...好主意。我不太喜欢我的想法。我喜欢干净和基于模式。
  • 或者,将 bool 返回函数移到其他地方(不同的类或服务,远离控制器),只在 BaseController 中留下 Action。这样可以进一步清洁您的控制器并使事情更整洁。 :)
  • 我可以做一些类似传递代表的事情,比如CheckValues(Guid value1, string value2, Func<ActionResult, Guid> myMethodName)。然后我可以在失败时执行重定向,或者只运行一个返回视图的方法。
  • 似乎您应该为此使用操作过滤器,而不是基类方法。

标签: c# asp.net-mvc


【解决方案1】:

基类方法的替代方法是动作过滤器。您的控制器操作可能如下所示:

[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 的那行会缩短您的操作,因此它实际上永远不会被执行——重定向会在请求到达您的控制器操作之前发生。

【讨论】:

  • 我知道我见过类似的东西,但记不起名字了。谢谢。研究。
  • 漂亮干净的解决方案。
  • 还有一个问题。有没有办法在过滤器中获取Request.Url.AbsolutePath
  • @MKenyonII 是的,你可以在filterContext.HttpContext.Request.Url.AbsolutePath找到它
猜你喜欢
  • 1970-01-01
  • 2011-09-27
  • 1970-01-01
  • 2017-02-15
  • 2016-05-13
  • 2018-10-06
  • 2016-06-27
  • 1970-01-01
  • 2017-05-21
相关资源
最近更新 更多