在我的 MVC4 应用程序中,根据您是否登录(在我的情况下为 FormsAuthentication),有些操作需要表现不同。
例如,我有一个具有“RenderAccountAndProfile”方法的 AccountController。如果注销,相应的局部视图会显示登录提示和按钮。如果用户已登录,则会显示用户的个人资料链接以及注销按钮。
到目前为止,我在项目中采用的方法是简单地使用 if 语句......
if (HttpContext.User.Identity.IsAuthenticated)
{
...
}
else
{
...
}
但是,我刚刚创建了一种我认为是这种方法的相当优雅的替代方案。
我创建了一个名为 AnonymousUsersOnly 的新属性,它非常简单:
public class AnonymousUsersOnlyAttribute : System.Web.Mvc.ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(System.Web.Mvc.ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
return !controllerContext.HttpContext.User.Identity.IsAuthenticated;
}
}
我的 AccountController 类装饰有 Authorize 属性。这使我能够拥有以下代码:
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
[AnonymousUsersOnly]
[ActionName("RenderAccountAndProfile")]
public ActionResult RenderAccountAndProfile_Anonymous()
{
// create a "logged out" view model
return Content("**NOT LOGGED IN** - LOG IN HERE");
}
[ActionName("RenderAccountAndProfile")]
public ActionResult RenderAccountAndProfile_Authorized()
{
// create a "logged in" view model
return Content("**LOGGED IN** - LOG OUT");
}
}
我非常喜欢这种方法,因为我的操作方法符合单一职责原则。每种方法现在只处理登录情况或注销情况。我不再需要任何“if”语句来引导流量。
这也应该使单元测试更容易,因为每个方法现在只关注一个结果,而不是两个。我们可以编写单元测试来分别测试每个结果,调用不同的方法。
显然,我不能有两个具有相同签名的方法,所以这就是我必须使用 ActionName 属性的原因。
我会很感激你在这里的批评。你认为这是一个优雅的解决方案吗?这种方法的优缺点是什么?这会带来哪些安全隐患/风险?