Note that there are some explanatory texts on larger screens.

plurals
  1. POSingle Responsibility Principle in MVC controllers. Critique required
    primarykey
    data
    text
    <p>In my MVC4 app, there are some actions that need to behave differently depending on whether you are logged in (FormsAuthentication in my case) or not.</p> <p>For example, I have an AccountController that has a method "RenderAccountAndProfile". If logged out, the corresponding partial view displays a log in prompt and button. If a user is logged in, the user's profile links appear, alongside a log out button.</p> <p>The approach I've taken thus far in projects is to simply have an if statement along the lines...</p> <pre><code> if (HttpContext.User.Identity.IsAuthenticated) { ... } else { ... } </code></pre> <p>However, I've just created what I think is a reasonably elegant alternative to this approach.</p> <p>I have created a new attribute called AnonymousUsersOnly, which is very simple:</p> <pre><code>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; } } </code></pre> <p>My AccountController class is decorated with the Authorize attribute. This then enabled me to have the following code:</p> <pre><code>[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"); } } </code></pre> <p>I quite like this approach because my action methods conform to the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle" rel="nofollow">Single Responsibility Principle</a>. Each method now only deals with either a logged in situation or a logged out situation. I don't need any "if" statements directing the traffic any more.</p> <p>This ought to make Unit Testing easier too, since each method is now only concerned with one outcome, not two. We can write unit tests to test each outcome separately, calling different methods.</p> <p>Clearly, I can't have two methods with the same signature so that's why I have to use the ActionName attribute.</p> <p>I would appreciate your critique here. Do you think this is an elegant solution or not? What are the pros and cons to this approach? And what security implications/risks could there be with this?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload