[英]Need recommendation for global, targeted redirects on ASP.NET MVC site for multiple differing conditions
我正在使用ASP.NET MVC应用程序,管理员可以在其中添加新用户并标记他们以完成其他信息,然后他们才能使用网站的其他功能。 例如,我们有一个“ ForcePasswordReset”布尔值,以及完成安全问题的要求。 我们没有为这些用户使用Active Directory。
最终,这是我想要实现的行为:
最初,我将支票直接放入Login Controller ActionResult中。 但这仅解释了登录操作。 下面是一个简短的代码示例。
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid)
{
// ...
// Does the user need to complete some missing information?
if (externalUser.IsSecurityQuestionInfoComplete == false)
return RedirectToAction("ChangeSecurityQuestions", "MyInfo");
if (externalUser.ForcePasswordReset)
return RedirectToAction("ChangePassword", "MyInfo");
// Login was successful
return RedirectToLocal(returnUrl);
}
}
这种方法的一个问题是,在那些目标视图中还存在其他超链接,用户可以在其中导航离开目标界面。 因此,例如,定向到ChangeSecurityQuestions视图的用户只需单击即可。
登录的用户可以随时更改这些设置。 我可以为更改密码和安全性问题创建重复的视图,这些视图仅适用于这种情况,在这种情况下,用户被迫更新这些值。 为了保持DRY并减少维护,我想在两种情况下使用相同的视图(仅想编辑该信息的用户和被迫编辑该信息的用户)。 但是,如果替代方案更糟,尝试在这方面保持DRY可能会出错。
我开始在助手类中编写一种方法来转移这些用户的权限,尝试类似的方法。
/// <summary>
/// Check scenarios where the ExternalUser needs to complete some missing information, and divert as necessary.
/// </summary>
public static void divertExternalUserAsRequired(Controller controller, ExternalUser externalUser)
{
if (externalUser.IsSecurityQuestionInfoComplete == false)
return controller.RedirectToAction("ChangeSecurityQuestions", "MyInfo");
if (externalUser.ForcePasswordReset)
return controller.RedirectToAction("ChangePassword", "MyInfo");
}
但是由于保护级别的原因,该RedirectToAction无法访问。 而且,似乎不建议这样做( 是否可以在自定义AuthorizeAttribute类内使用RedirectToAction()? )。 而且我不喜欢通过在整个地方粘贴此检查来增加我的控制器的想法。
UtilityHelpers.divertExternalUserAsRequired(this, externalUser);
建议使用什么方法来处理这种情况? 我认为这是在全局范围内实现的,可以在加载任何相关视图时运行检查。
谢谢你的帮助。
如果我正确理解了您的问题,那么您可以使用几种选择。
一种选择是检查Global.asax.cs
类中Application_BeginRequest
中的必要条件。 在每个请求的开始都会调用此方法,如果条件失败,则可以像下面这样加载其他控制器操作:
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (!externalUser.IsSecurityQuestionInfoComplete)
{
var routeData = new RouteData();
routeData.Values["action"] = "MyInfo";
routeData.Values["controller"] = "ChangeSecurityQuestions";
RequestContext requestContext = new RequestContext(new HttpContextWrapper(Context), routeData);
IController errorController = new ChangeSecurityQuestionsController();
errorController.Execute(requestContext);
requestContext.HttpContext.Response.End();
}
}
您可以使用的另一种选择是创建并注册全局动作过滤器 。 正如您在问题中提到的那样,您不喜欢用这些条件检查乱扔控制器的想法。 通过注册全局动作过滤器,您的控制器可以完全不知道针对它执行的动作过滤器。 您需要做的就是在Global.asax.cs
注册操作过滤器,如下所示:
protected void Application_Start()
{
...
GlobalFilters.Filters.Add(new SecurityQuestionCompleteFilter());
...
}
我希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.