ASP.Net MVC: PhotoView Lessons – Getting Around A Master Page Model

Original About PhotoView Here

I’ve started to take the PhotoView site and move it toward a full blow site application. Not sure why, but then again why shouldn’t I? Don’t have a good reason? Pbbbbbbtttt jog off.

One thing I ran into yesterday while working on it, as I’ve added authentication to the site (An update I’ll post sometime this week I think), is having a menu show or not show based on the user being logged in or and admin or whatever. What I don’t like doing is having to call methods from the “framework” if I can just add a property to a model. There are various reasons why, ranging from the fact mark up errors don’t blow up compile time to the idea that the model should take care of those things. Now you can’t always follow this rule as it’s obvious I use the CreateUrl method like it’s a bat in a shed. (I have no idea what that means) However, a certain amount of lock down is nice and the Create method is an extension method so it doesn’t look like I’m cheating… Am I right?

So here’s the situation, I would like to have a model that has two properties UserIsLoggedIn and UserIsAdmin so I can do magic like:

  <%
    if(Model.UserIsAdmin)
    {
  %>
      <a href="Admin/DoStuff" > Admin Stuff </a>
  <%
    }
  %>

Now this would seem to be simple, you would think having the master page inherit from the generic version of ViewMastePage:

  Inherits="System.Web.Mvc.ViewMasterPage<SomeModelClass>"

And the class would be something like this:

  public class SomeModelClass()
  {
    public Boolean UserIsAdmin { get; set; }
    public Boolean UserIsLoggedIn { get; set; }
  }

And the flowers would bloom, the sun would shine, and dogs and cats would live in harmony. And it works that way up until you actually run any given page with a strongly typed view. Then you get this error:

Sorry bro, but you need a hella cool model that is all like “Hey mom” to SomeModelClass.

I think I’m paraphrasing a bit but the idea to take from this is that all view models will have to inherit from the same model the master page is using. Yeah, basically a bit “go f— yourself” written into MVC. So either you follow this obviously easy and unhindering design choice or you do what all programmers must do at some point: Compromise. And I mean that in the real sense, not the in the relationship, better to bend than break even though you’re already broken sort of way.

Remember that little bit of self comfort I gave myself for the HtmlHelper extension CreateUrl, well it’s time to do that once again. So in a He’s Just Not That In To You sort of way (Yes I saw that movie. That’s the other version of compromise), I’m going to tell myself that it’s ok and that though it may be bad for most situations, I’ve heard that Sally’s friend in New York who is a programmer got away with it so I’ll most like get away with it too.

  public static class ViewMasterPageExtension
  {
    public static String CurrentUrl(this ViewMasterPage page)
    {
      return SiteMethods.GetCurrentUrl();
    }

    public static Boolean UserIsAdmin(this ViewMasterPage page)
    {
      return State.CurrentUser != null && State.CurrentUser.UserType == PhotoViewUserType.GetAdminType();
    }

    public static Boolean UserIsLoggedIn(this ViewMasterPage page)
    {
      return State.CurrentUser != null;
    }
  }

Yes it’s not on a model, yes it’s a work around, but I’d rather do this:

  if(this.UserIsAdmin())

Than this:

  if(State.CurrentUser != null && State.CurrentUser.UserType == PhotoViewUserType.GetAdminType();)

And in the end, isn’t what make my life easier the main goal of existence?

Is it me or does Sam Neil look beyond creepy in this imdb photo?