tags:

views:

34

answers:

1

I am using MVC 2.

I have a BaseController class that every Controller uses. In this base controller class there is a property called IsAdministrator. I need to use this method in my view's HTML part. How would I do this?

EDIT:

My property in my BaseController is defined like this:

public bool IsAdministratorUser
{
   get { return ... }
}
+6  A: 

One way would be to use an HTML helper:

public static class HtmlExtensions
{
    public static bool IsAdministrator(this HtmlHelper htmlHelper)
    {
        var controller = htmlHelper.ViewContext.Controller as BaseController;
        if (controller == null)
        {
            throw new Exception("The controller used to render this view doesn't inherit from BaseContller");
        }
        return controller.IsAdministrator;
    }
}

And in your view:

<% if (Html.IsAdministrator()) { %>

<% } %>

UPDATE:

@jfar's comment about the MVC paradigm is correct. Here's what you could do in practice to implement it. You could define a base view model class that all your view models derive from:

public class BaseViewModel
{
    public bool IsAdministrator { get; set; }
}

and then write a custom action filter attribute which will execute after the action and set the property:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AdministratorInjectorAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResultBase;
        if (result != null)
        {
            // the action returned a strongly typed view and passed a model
            var model = result.ViewData.Model as BaseViewModel;
            if (model != null)
            {
                // the model derived from BaseViewModel
                var controller = filterContext.Controller as BaseController;
                if (controller != null)
                {
                    // The controller that executed this action derived
                    // from BaseController and posses the IsAdministrator property
                    // which is used to set the view model property
                    model.IsAdministrator = controller.IsAdministrator;
                }
            }
        }
    }
}

And the last part is to decorate the BaseController with this attribute:

[AdministratorInjector]
public abstract class BaseController : Controller
{
    public bool IsAdministrator { get; set; }
}

Finally if your view is strongly typed to a model that derives from BaseViewModel you could directly use the IsAdministrator property:

<% if (Model.IsAdministrator) { %>

<% } %>

Probably a bit more code than the HTML helper, but your consciousness about respecting MVC paradigm will be clear.

Darin Dimitrov
+1 darin, nice one as usual :). i'd add that it's also useful to cache that kind of helper call into a variable if it'll be used in a few places inside the view. i.e <% bool isAdminUser = Html.IsAdministrator();%> and then just refer to <% if (isAdminUser ) { %> etc, etc..
jim
@Darin: You are a boffin at MVC :)
Brendan Vogt
@Darin: How would I get the IsAdministrator to display in the Html helper? It's not currently there?
Brendan Vogt
You use the extension method to the `HtmlHelper` class. This extension method *adds* the `IsAdministrator` method. You need to import the namespace in which the `HtmlExtensions` class is defined so that you could see the IsAdministrator method in the view: `<%@ Import Namespace="SomeNamespace.In.Which.You.Declared.The.Class" %>`. You could also use the `namespaces` section in web.config to avoid declaring it in each view in order to bring the extension method into scope.
Darin Dimitrov
@Darin: Thanks.
Brendan Vogt
@Darin Dimitrov - I'm really surprised to see you answer without a scolding. @Brendan Vogt This breaks MVC in a bad way. The best approach would be to pass IsAdministrator as part of a View's model and not reach back into the controller.
jfar
@jfar, that's a good point that I've translated into a practical example in my update.
Darin Dimitrov