3

My base controller has:

[Authorize(Roles = "sys_admin")]

I want to have one action in a controller that's different and is available to "user" and "sys_admin". Can I override and how do I do that?

Also any suggestions on what else I could put in a base controller that might make my coding simpler. For example what's in your base controllers?

tereško
  • 56,151
  • 24
  • 92
  • 147
Samantha J T Star
  • 26,790
  • 72
  • 224
  • 390

5 Answers5

3

Anything that you use in every controller - attributes, methods, properties, etc. The same stuff you would put in any base class.

jrummell
  • 41,300
  • 17
  • 110
  • 165
  • 2
    +1. The general rule as always: Everything that you find yourself duplicating should be moved to the base class. – jgauffin Nov 08 '11 at 14:54
3

Just to add to the discussion, I have a few extra utility methods in my shared controller. I write a bunch of little apps for corporate use, so I try to repeat code as little as possible here.

  • getContext(): Puts together an object containing user info like IP, hostname, id, etc. for logging purposes.
  • Shared Views/Partials such as Error, Default, and Redirect (used for redirecting ajax requests).
  • RedirectToError(): I created this to use similar to RedirectToAction. I load up an ErrorObject with info, throw it in session, and return a Redirect to my Error page.
  • General logging and tracing methods so I can quickly spit out information to a file.
  • I override OnActionExecuting and check if my session is still valid and redirect to login if its not. Probably better with attributes...went with quick and dirty. Also trace Url.PathAndQuery for debugging here.
  • Any data access actions that I would use across views with ajax, like loading up a list of departments.
  • OnException is overridden, as well.

That's what I got in mine so far.

IronicMuffin
  • 4,154
  • 11
  • 45
  • 86
2

In my base controllers I actually put some utility method ([NonAction]) collected over time. I prefer to add functionalities to Controllers by decorating with Attributes if possible.

Lately my base controller has:

  • some Properties for retrieving information about the current user (my app specific informations, not the User.Identity stuffs)
  • A simple protected override void OnException(ExceptionContext filterContext); override for at least logging unhandled exception and have some sort of automatic notifications
  • A bunch of Cookies related methods (WebForms auth cookies management for example)
  • A bunch of usefull standard attributes (usually [Authorize], [HandleError], [OutputCache]) in its declaration.
  • some standard method for preparing widely used json data types on the fly (when possible I prefer to have a standard json object with ErrorCode, ErrorMessage and a UserData).

With time you'll find more and more utilities to keep with your controllers, try to keep an assembly with the simpler ones (avoiding heavy dependencies), will come handy with your next MVC projects. (the same goes for Helpers and to some degree also for EditorTemplates).

For the Authorize Attribute part, well, I think the cleanest way is to write your own AuthorizeAttribute class, specifically a NonAuthorizeAttribute. I think I've also seen it somewhere on SO.

You can also play with the Order Property of the default AuthorizeAttribute - put different Order in BaseController and in Action, in order to have Action's one executed first, but I cannot recall if you can actually break the Attributes processing chain.

Regards,

M.

BigMike
  • 6,260
  • 1
  • 21
  • 23
  • 2
    don't use `OnException` in the controllers. Use filters to log. Derive HandleErrorAttribute and add your logging in it. The switch to your implementation in global.asax – jgauffin Nov 08 '11 at 14:40
  • @jgauffin: Yes, you're 100% right, Attributes and Filters are way better than overriding methods, but sometimes the quick and dirty override, just get the job done. – BigMike Nov 08 '11 at 14:47
  • 1
    .. and leaves a mess for someone else to clean up ;) – jgauffin Nov 08 '11 at 14:49
  • Maintenance is the real big deal. MVC helps a lot, still when thinking about future, gives me the creeps. This would be a nice starting point for a deep discussion about best practices with MVC, a bit off topic on SO, but very valuable to us all. I'm actually working on a big project and I feel like it's getting out of our hands, but there's no time to stop and think about reorganizing it well. – BigMike Nov 08 '11 at 14:56
  • 1
    Read my blog. Got several entries about MVC and code maintenance in general (link in my profile) – jgauffin Nov 08 '11 at 14:59
1

We cant tell you what you need in your base controller, you have to reveal these kind of thing as you implement your controllers and see repeating code.. Dont hesitate to refactor these things to your BaseController, and keep in mind, that maybe you should have 2 or more BaseControllers, or 2-layer hierarchy of BaseControllers.

I give you two tips, what i always have in my BaseController :

  1. super-useful helper method for interface-based model binding :
protected T Bind<T, U>()
   where T : U, new()
   where U : class
{
   T model = new T();
   TryUpdateModel<U>(model);
   return model;
}

You can then have multiple "sets" of properties you want to bind in different scenarios implemented as interfaces, and simple model bind your object (even existing object, from DB) with incoming values.

2.If you use custom AcionResults (maybe your specific Json builders etc.), make your "shortcuts" methods in BaseController. Same thing as View() method is shortcut for return new ViewResult(...)

rouen
  • 4,669
  • 2
  • 23
  • 48
0

To add more to the good responses already here - caching caching caching caching

See Disable browser cache for entire ASP.NET website

Community
  • 1
  • 1
Adam Tuliper - MSFT
  • 29,569
  • 4
  • 49
  • 68