如何为所有控制器仅应用一次覆盖方法

时间:2017-10-14 03:13:12

标签: c# asp.net-mvc-3

我正在尝试实现以下逻辑:

每当创建新用户时,都会分配默认的硬编码密码。如果新创建的用户已登录,系统将强制用户更改其默认密码

我已经在我的控制器中使用此代码成功实现了上述逻辑:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //Check if authenticated
        if (filterContext.HttpContext.User.Identity.IsAuthenticated && !filterContext.HttpContext.Request.RawUrl.Equals("/Account/ChangePassword") && !filterContext.HttpContext.Request.RawUrl.Equals("/Account/LogOff"))
        {
            //Get user Data
            MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
            if (currentUser.GetPassword().Equals("password"))
            {
                filterContext.Result = new RedirectToRouteResult(
                                       new RouteValueDictionary 
                                        { 
                                            { "controller", "Account" }, 
                                            { "action", "ChangePassword" } 
                                        });
            }
        }
    }

但是,现在我必须将此代码复制粘贴到我的所有控制器。这是否不尊重mvc3中的DRY原则?

如果是,我应该在何处或如何放置此代码,以便可以全局实施到我的所有控制器? 我试图将它粘贴在Global.asax中,但我收到一条错误,上面写着"没有找到合适的方法来覆盖"

2 个答案:

答案 0 :(得分:0)

如前面评论部分中其他人所述,您可以使用 基本控制器 或使用 操作过滤器

目前,您可以考虑使用actionfilter这样创建。

public class YourActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {

    }
}


     [YourActionFilter]
     public class HomeController : Controller
     {
          public ActionResult Index()
          {
               return View();
          }

          public ActionResult About()
          {
               return View();
          }
     }

您可以在MS doc

中找到更多详细信息

答案 1 :(得分:0)

使用全局过滤器。以下是动作过滤器的示例。

public class ForceLoginActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //Check if authenticated
        if (filterContext.HttpContext.User.Identity.IsAuthenticated && !filterContext.HttpContext.Request.RawUrl.Equals("/Account/ChangePassword") && !filterContext.HttpContext.Request.RawUrl.Equals("/Account/LogOff"))
        {
            //Get user Data
            MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
            if (currentUser.GetPassword().Equals("password"))
            {
                filterContext.Result = new RedirectToRouteResult(
                                       new RouteValueDictionary
                                        {
                                        { "controller", "Account" },
                                        { "action", "ChangePassword" }
                                        });
            }
        }
    }
}

用法

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new ForceLoginActionFilter());
    }
}

参考:Filtering in ASP.NET MVC

  

注意: Never use a base controller in ASP.NET MVC。这几乎总会导致创建难以维护的god object