views:

605

answers:

2

We're currently rewriting our organizations ASP.NET MVC application which has been written twice already. (Once MVC1, once MVC2). (Thank god it wasn't production ready and too mature back then).

This time, anyhow, it's going to be the real deal because we'll be implementing more and more features as time passes and the testruns with MVC1 and MVC2 showed that we're ready to upscale.

Until now we were using Controller and Action authorization with AuthorizeAttribute's.

But that won't do it any longer because our views are supposed to show different results based on the logged in user.

Use Case: Let's say you're a major of a city and you login to a federal managed software and you can only access and edit the citizens in your city.

Where you are allowed to access those citizens via an entry in a specialized MajorHasRightsForCity table containing a MajorId and a CityId.

What I thought of is something like this:

Public ViewResult Edit(int cityId) {
    if(Access.UserCanEditCity(currentUser, cityId) {
        var currentCity = Db.Cities.Single(c => c.id == cityId);
        Return View(currentCity);
    } else {
        TempData["ErrorMessage"] = "Yo are not awesome enough to edit that shizzle!"
        Return View();
    }

The static class Access would do all kinds of checks and return either true or false from it's methods.

This implies that I would need to change and edit all of my controllers every time I change something. (Which would be a pain, because all unit tests would need to be adjusted every time something changes..)

Is doing something like that even allowed?

+2  A: 

That's pretty much what I'd do for a decent sized application.

I would return a generic error view return View("Error"); if the user doesn't have any access so you don't need to handle the an error message on every View.

Conceptually, this (the Controller) is where the logic determining what View to return should lie. It stops business logic bleeding into the View.

You could abstract out certain role-dependant parts of the page to partial views to keep the clutter down:

 <% if (User.IsInRole("Admin")) { %>
      Html.RenderPartial("AdminPanel");
 <% } %>
David Neale
+1  A: 

Have you thought about writing your own Action Filter Attribute?

That way you could just decorate your controller with the attribute and save you a lot of copying and pasting, plus if it ever needs to be changed then its only done in one place.

If you get the source code for MVC from Codeplex you can see how the Authorize attribute is done and modify that.

Simon G