Grails - Write method available in any controller - grails

I'm quite new into groovy / grails world, so forgive for asking simple question. I'm pretty sure this can be done by meta-programming, that is injecting method into definition of grails controller class or so. Can anyone point me where should this injection be written (Bootstrap.groovy?).
I'm trying to create currentUser() method with Spring-security-core plugin that I could use in any controller.

Your question is answered in these two posts:
How can I add common actions to controllers without using inheritance?
Add methods to controllers
However there are a couple of other approaches you might consider ...
You could just inject a "SecurityService" into controllers that need to know the current user and put "getCurrentUser" on that.
You could use a Grails filter to add "currentUser" to the params map available to all controllers. I like that approach as I usually use a filter to implement security anyway. The filter can also add it to all models prior to view rendering so all your views have access to it.

Related

How to use custom authorize attribute in razor view

I have created a class CustomAuthorizeAttribute:AuthorizeAttribute for authorization, but I am unable to authorize in the razor view like #if(User.IsInRole("some role"));, but what I want is #if(CustomAuthorizeAttribute(My Parameters)) for my authorization.
How to do that?
AuthorizeAttribute works by placing it on an action method, a controller, or as a global filter. It is not possible to use MVC filters inside of views (or at least not without a lot of work).
I suggest you ask a different question and narrow it to your requirements. There must be some reason why you are attempting this, but it is impossible to work out what you need to do (or if there is a much simpler approach) from your question.

ASP.NET Mvc - AutoMapper Best Practice - Performance

I've not looked at the AutoMapper source code yet but was just about to make some changes to an API controller in my solution and had a thought.
The way I like to code is to keep my controller methods as concise as possible, for for instances I make use of a generic Exception attribute to handle try{}catch{} scenarios.
So only the code that is absolutely relevant to the controller action is actually in the action method.
So I just arrived at a situation where I need to create an AutoMapper map for a method. I was initially thinking that I would add this (as I have done previously) to the controller constructor so its available immediately.
However, as the controller grows following this pattern may introduce a lot unnecessary AutoMapper work depending on the controller action method which is invoked.
Considering controllers are created and destroyed per request this could get expensive.
What are some recommendations around this? Considering AutoMapper is accessed statically I was wondering if it's internals live beyond the request lifetime and it internally checks for an existing map before creating a new one each time CreateMap() is invoked?
You should create your maps (CreateMap) once per AppDomain, ideally when this domain starts (Application_Start).

Grails security check

I am using spring-security-core and I have got more than ten controllers, I want to check whether user is logged in all the actions, I know one method of doing if(springSecurityService.isLoggedIn()) in all the actions, Is there any other way to do it, Instead of writing the same logic in all the actions/controllers
If you'd like to deny access to the actions entirely, there are a few ways of doing it.
You can put the #grails.plugins.springsecurity.Secured annotation on the controller class, or action method. You can also specify what needs authentication by URL by creating a request map. You can either create a Requestmap domain object, or you can create a static request map in your Config.groovy with the grails.plugins.springsecurity.controllerAnnotations.staticRules map.
There are more details in the Spring Security Core manual.
If it were me I would take ataylors answer one step further. Do as he said, but instead of copying and pasting the same code in all of your controllers just put it in the Controller.groovy template once then run the generate-all command. Templates are very powerful for things like this, and if you keep your templates up to date you can easily change 10 controllers, or 100 controllers as needed if/when your application evolves.
How to install templates:
http://grails.org/doc/latest/ref/Command%20Line/install-templates.html

Grails: reusing an action

I'm building an application that among other things allows users to upload documents. I have the basic create/view actions working just fine, but i'd like to reuse this action in other places.
I want to know if anyone has a pointer for how to do this. There doesn't seem to be a very good way of doing this.
Here are a few ways i've considered:
Try to do a chain(). This doesn't work since chaining does a GET, and to upload you need a POST.
Break out the main business logic into the Grails "service", and make two actions that use the same code.
Use a JS modal window. I've been thinking a modal that contains an iframe to an "unskinned" version of the document upload. The trick here is to get the window to close when the upload is done.
Thanks
--Matthias
I don't care for the extending controller method. In fact, I avoid inheritance when possible. I'd rather put the common code in a service class and reuse it that way.
You can use a base controller class, and place the common functionality there. Then extend the base controller and call the method from other action methods.

asp.net mvc is it proper to create an instance of a controller in another controller's constructor?

i have several controllers which will all be using common functionality. So i have separated that functionality into a separate controller.
the shared controller needs a parameter specific to which controller it is being used from, and needs to return views based on id ints passed to it.
So, one idea is to create an instance of SharedController(int callingControllerId) in the constructor of each of the controllers that will be using it. Then, within the action methods of each controller, call the action methods of the shared controller, passing appropriate ids, and returning views from SharedController to the calling controller, which would return the view to be rendered.
Does this sound right? Should controllers be creating other controllers in MVC?
Thanks!
Absolutely not although having your controller inherit from a shared, base controller is pretty common.
public KittyController : MySharedBaseController
{
}
Like Greg Roberts points out that although having a ControllerBase is common it is not always the best place to store shared functionality. MVC has a lot of extensibility points and picking a narrow place to wedge in your code is a lot better than smushing tons of things into a base controller.
I would agree that a base controller is pretty common, but I'm not sure it's the right solution for what you are describing.
Without knowing what is exactly shared it's a bit hard to figure out, but the whole bit of your base controller knowing specifics about the controllers that are inheriting from it smells a bit.
Here are a couple things to consider.
Composition is almost always better than inheritance. Great article on this
Base controller should have common methods/properties, for example mine have some properties of getting the current user and a generic method for calling external services, but not specific things from inheriting controllers. Rule of thumb, if it's not needed by more than 1 controller, than probably not good in base implementation.
It's possible that some of the new MVC 2 features might solve what you are doing. Look at render action.
As with anything in software, there are tons of ways to solve the problem, so ultimately do it the way that makes the most sense to you and your team.
Controllers are constructed by the ASP.NET MVC runtime and you should never be constructing them in your own code. It sounds like you don't really need a separate controller, you just need another class that you aggregate in the controller, and use as a service. This is perfectly acceptable. In fact, I would go so far as to say that in general controller should be delegating their work to other "service" classes and shouldn't have much responsibility (especially domain logic) in and of themselves.
I don't know the details of why this service class needs to know what controller it is being called from, but perhaps you can just declare an enum that defines the different use cases, and pass that in in its constructor. Actually having the service class know about different controllers would be a code smell for me.

Resources