- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的 MVC4 应用程序中,有些操作需要根据您是否登录(在我的例子中是 FormsAuthentication)而采取不同的行为。
例如,我有一个 AccountController,它有一个方法“RenderAccountAndProfile”。如果注销,相应的局部 View 会显示登录提示和按钮。如果用户已登录,则会显示用户的个人资料链接以及注销按钮。
到目前为止,我在项目中采用的方法是简单地使用 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");
}
}
我非常喜欢这种方法,因为我的操作方法符合 Single Responsibility Principle .每个方法现在只处理登录情况或注销情况。我不再需要任何“if”语句来引导流量。
这也应该使单元测试更容易,因为每个方法现在只关心一个结果,而不是两个。我们可以编写单元测试来分别测试每个结果,调用不同的方法。
很明显,我不能有两个具有相同签名的方法,所以这就是我必须使用 ActionName 属性的原因。
非常感谢您的批评。您认为这是一个优雅的解决方案吗?这种方法的优缺点是什么?这会带来哪些安全隐患/风险?
最佳答案
您这里遇到的问题是策略模式问题。你已经实现了一个(非标准的)策略模式,而且实现非常巧妙。我担心它太聪明了。这种聪明使得代码的作用对于外行来说不那么明显。
顺便说一句,我不想打扰。我经常将 Controller 编写为域对象/服务上的非常薄的适配器。因此,我愿意以务实的态度来完善 Controller 的设计。在轻微的设计问题和明显的代码之间做出决定时,总是选择明显的代码。
如果您有更厚的 Controller ,或者出于其他原因真正关心这里的这个问题,您可能会考虑更传统的策略模式,或许可以借助一个抽象工厂来提供基于身份验证状态的不同策略实现。这符合您的设计目标,并且其他程序员(如果他们了解设计模式)会更加熟悉。
综上所述,我认为保留您的聪明解决方案不会对任何事情造成太大伤害。我很想改名;对我来说,拒绝似乎是一个奇怪的动词。也许 AnonymousUsersOnly
,这对 future 的程序员来说会更容易交流。
关于asp.net-mvc - MVC Controller 中的单一职责原则。需要批评,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13714250/
这是建议的解决方案(我确实搜索了相同的解决方案 - 没有成功) public abstract class AsyncCache { /** * an ato
在挖掘一些旧的源代码时,我看到了以下内容: my $module = $some{module}; eval "require $module"; die "Bad module\n$@" if $@
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 3年前关闭。 锁定。这个问题及其答案是loc
我设计了以下方法来捕获整个AS3应用程序中的错误: 在Document类中,定义以下方法: //This is the handler for listening for errors protect
我想知道是否有人看到任何可能导致此代码出现问题的内容。我知道我可以使用其他方法/API 调用来完成此操作,但我正在尝试为我自己的平台独立性奠定基础?/跨平台互斥框架。 显然我需要做一些#ifdef 并
我一直在阅读大量有关实现响应式移动下拉菜单的不同方法的资料。纯 CSS 解决方案对我来说似乎有点笨拙,但我讨厌依赖 javascript 来处理像导航菜单这样重要的事情。我想到的是使用 javascr
我即将构建我的第一个基于 Lisp 的严肃项目:一个需要扩展到数以万计的用户(不是同时的 - 最多可能是数百个同时)的 Web 应用程序。 我打算使用的堆栈如下所示: Weblocks具有 Berke
我正在寻找 PerlCritic 的等价物对于 PHP。 PerlCritc 是一个静态源代码分析器,它对代码进行 qritiques,并就从未使用的变量到处理数据的不安全方式到几乎所有内容的所有内容
我正在编写一个 perl 脚本,该脚本需要在调用外部程序之前设置许多环境变量。我的代码有形式 $ENV{'VAR1'} = "value1"; $ENV{'VAR2'} = "value2
我是一名优秀的程序员,十分优秀!