如何为所有控制器仅应用一次覆盖方法
How to Apply Override Method only once for all controller
我正在尝试实现以下逻辑:
每当创建新用户时,都会分配一个默认的硬编码密码。如果新创建的用户登录,系统将强制用户更改其默认密码
我已经在我的控制器中使用这段代码成功实现了上述逻辑:
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 中,但出现错误 "No Suitable Method Found to Override"
正如其他人之前在评论部分所述,您可以使用 base controller 或使用 动作过滤器.
目前,您可以考虑使用像这样创建的 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
中找到更多详细信息
使用全局过滤器。这是动作过滤器的示例。
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());
}
}
NOTE: Never use a base controller in ASP.NET MVC. This will almost always lead to creating a god object that is difficult to maintain.
我正在尝试实现以下逻辑:
每当创建新用户时,都会分配一个默认的硬编码密码。如果新创建的用户登录,系统将强制用户更改其默认密码
我已经在我的控制器中使用这段代码成功实现了上述逻辑:
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 中,但出现错误 "No Suitable Method Found to Override"
正如其他人之前在评论部分所述,您可以使用 base controller 或使用 动作过滤器.
目前,您可以考虑使用像这样创建的 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
中找到更多详细信息使用全局过滤器。这是动作过滤器的示例。
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());
}
}
NOTE: Never use a base controller in ASP.NET MVC. This will almost always lead to creating a god object that is difficult to maintain.