Grails Filters vs Interceptor - grails

I have been studying Grails for quite a while now. And scanned a little bit about Filters and Interceptors. Both have almost the same functionality of tracking the sessions or redirecting unauthorized users in a particular controller.
But I'm confused when and why should I use Filter than Interceptor and vice versa.
Given that the Inceptors have two controller methods beforeInterceptor and afterInterceptor and for the Filters a three common closures before, after and afterView.
My questions is what are the pros and cons of using Filter against Interceptor or vise versa. In this manner we, developers, can decide when, where, and why we should use either Filter or Interceptor in a particular Controller to do some tracking, redirect, etc.

Use one or both interceptors in a controller when the interception logic only applies to that controller.
Use a filter when the logic applies to multiple (or all) controllers, or when you need to do something after the view is rendered (there's no interceptor equivalent of afterView), or if you just want to keep everything centralized in one place instead of spread across separate controller files.

The Old Filters (From Grails 2) are deprecated in Grails 3. The replacement to the Filters are Interceptors.
The use of interceptors is for actions such as: authentication, loggin, etc.
The interceptors (as their name implies) are intercepting the incoming web requests and trigger a related actions. The actions are defined in the related Controller.
The Interceptors have some major benefits (over the Filters) such as support for static compilation, and enable flexible configurations.
These are the main 3 methods of the Interceptor:
- boolean before() { true }
- boolean after() { true }
- void afterView() { }
The Iterceptors are configured as Spring Beans (in the Spring application context) and are configured to be auto-wired by their names.

Related

Make Grails action available only for includes

I have a Grails controller with multiple actions. For now all actions are available for user calls (I can access them from my browser), even the ones that should be called only from withing the g:include tag. I want to restrict access to such actions from the browser. I cannot mark action as protected because in this case I will not be able to include this action in a view for another controller.
Is there any practice how to encapsulate actions in such situations?
The way to “protect” actions from being accessible via a URL is to not provide a URL mapping to them. The default url mapping looks something like this…
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
// ...
}
}
That “/$controller/$action?/$id?(.$format)?” mapping is convenient for simple crud apps and demos well but for any substantial app you should almost always remove that. Without it, only the actions you explicitly expose are accessible.

HTTP module vs action filter in asp.net-mvc

I am developing an application in asp.net MVC3 and I have the following questions:
When should I write an HTTP module and when should I write an action filter?
Filter are more MVC approach of doing thing whereas Http Module are more of ASP.NET way of doing thing. Both serve similar purpose by providing hook in the processing pipline.
HttpModule is more generic and when you want some thing to be processed on every request. Filters are useful for adding action specific behaviour.
If you want some thing to be executed only once per Http Request, you should use an HttpModule. ActionFilter may get executed several times during a request until and unless you check IsChildActionOn.
HttpModule are called before and after the request handler executes. They are intended to enable a developer to intercept, participate, or modify each request. There are 22 available events that can be subscribed to that enables the module to work on the request in various stages of the process. The events are useful for page developers who want to run code when key request pipeline events are raised. They are also useful if you are developing a custom module and you want the module to be invoked for all requests to the pipeline.
Filters are designed to inject logic in between MVC request life cycle. Specifically before and after de action is invoked, as well as, before and after the result is processed. Filters provide users with powerful ways to inspect, analyze, capture and instruments several things going around within MVC projects. As of MVC5, there are 5 types of filters :
Authentication
Authorization
Action
Result
Exception
So if you want to intercept, participate, or modify in a specific of the 22 events in the http request pipeline choose the modules. If your logic is is strictly related to the action method you better server overriding one of the following ActionFilterAttribute methods:
OnActionExecuting
OnActionExecutted
OnResultExecuting
OnResultExecuted
HttpModule is how IIS allows an Web application to override the default behavior or add custom logic by letting you attach event handlers to HttpApplication events.
Different IIS modes (Integrated or Classic) even use has different Web.config settings.Reference:
http://msdn.microsoft.com/en-us/library/ms227673(v=vs.100).aspx
Example: redirect non-www to www URLs
public void Init(HttpApplication application)
{
application.PreRequestHandlerExecute += this.Application_PreRequestHandlerExecute;
}
private void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
Uri requestUrl = HttpContext.Current.Request.Url;
string host = requestUrl.Authority.ToLower();
if (!host.StartsWith("www"))
{
HttpContext.Current.Response.Redirect(requestUrl.Scheme + "://www." + host + requestUrl.PathAndQuery);
HttpContext.Current.Response.End();
}
}
An Action Filter is an attribute decorating controllers or action methods. It is an abstraction layer between MVC routing and action methods. With action filters, we can apply same logic to multiple controllers or action methods. for example, custom logging.

keeping asp.net mvc controller size down

I have a Controller. "OrderController". Currently it's 1800 lines. I like to reduce the size. I'm using static helper methods which is fine but i'm using ninject to call my repositories so don't have access to the repositories in the static methods without passing the properties in.
What are some good approaches for reducing controller noise?
How to get a Thin Controller
Refactor reusable functionalities that can apply to multiple types of output to ActionFilters. Consequence: Less repetitive code, thinner Controller actions, quicker future development
Refactor reusable functionalities that apply to a specific type of output to a custom ActionResult. Consequence: Less repetitive code, thinner Controller actions, quicker future development
Leverage ModelBinders to bind your input values to complex objects that are injected into your Controller action. Consequence: You don't need to handle the actual HTTP input (RouteData, Form values, querystring parameters) at all in your controller. You can also handle data validation in your model binder.
Implement Dependency Injection via a custom ControllerFactory. Consequence: You don't need to construct services in your Controller.
Refactor single Controllers with an excessive amount of Controller actions into multiple Controllers. Consequences: Your code becomes more maintainable.
Move your static helper methods to static classes. Consequence: Your methods become reusable by multiple controllers and you have less bloated code in the Controller, so it is easier to maintain and make changes to your app.
Other Notes
Plenty of open source resources exist to help accomplish these tasks. I definitely suggest looking into the MvcContrib project. They have a FluentController base class that was designed with building thin Controllers in mind. Also, I upvoted Darin because the video he recommended is helpful, so check it out
No way should there be that much code in your controller. I suspect you haven't separated your concerns.
I would have a look and a think at the answer to this SO question:
ASP.NET MVC Patterns
In short:
Put the complexity into Service classes that perform a clear cut purpose, ie, to deliver what the controller needs.
The controller should just have the application logic, ie, it should just be acting as a kind of air traffic, uhmm, controller, sending requests this way and that based on app logic. That is pretty much its function in a nutshell. Other stuff doesn't belong in a controller.
My controllers look like:
[Authorize(Roles="Admin, Tutor, Pupil")]
public partial class CourseController : Controller
{
ICourseDisplayService service;
public CourseController(ICourseDisplayService service)
{
this.service = service;
}
public virtual ActionResult Browse(int CourseId, string PupilName, string TutorName)
{
service.Initialize(CourseId, 1, PupilName, TutorName, User);
service.CurrentStepOrder = service.ActiveStepIndex;
if (Request.IsAjaxRequest())
{
return PartialView(MVC.Courses.Course.Views._Display, service.ViewModel);
}
else
{
return View(MVC.Courses.Course.Views.Display, service.ViewModel);
}
}
note the service instantiation in the controller's constructor and the calls to service in the actions.
1800 lines!!!!!!!!! Holy mother of God. I would recommend you watching the following video about putting your controllers on a diet.

Any issues with always using ASP.NET MVC AsyncController instead of Controller?

We have a series of ASP.NET MVC controllers that all inherit from a single base controller (that inherits from the Controller class). We are now looking at creating some asynchronous actions, and was wondering if we'd run into any trouble if we just changed the base controller to inherit from AsyncController instead of Controller (meaning all of our controllers would inherit from AsyncController).
Jess,
In my opinion, you'll do no harm as the asynch functionality is only called into play when you follow the conventions of:
public class PortalController : AsyncController
{
public void NewsAsync(string city)
{
AsyncManager.OutstandingOperations.Increment();
NewsService newsService = new NewsService();
newsService.GetHeadlinesCompleted += (sender, e) =>
{
AsyncManager.Parameters["headlines"] = e.Value;
AsyncManager.OutstandingOperations.Decrement();
};
newsService.GetHeadlinesAsync(city);
}
public ActionResult NewsCompleted(string[] headlines)
{
return View("News", new ViewStringModel
{
NewsHeadlines = headlines
});
}
}
the convention being the addition of the News*Async* and the News*Completed* portions in the naming.
see:
async controllers in asp.net mvc 2
Observe that the controller class now derives from AsyncController rather than Controller. In addition, the News action method has been split into methods named NewsAsync and NewsCompleted, which are analagous to the Begin and End methods in asynchronous pages. Logically, the controller still exposes a single action method named News. But physically, the method implementation has been broken up using a variation on the async pattern used throughout the .NET framework.
If you don't change anything in your inherited controller code, then no async activty will be initiated. However, as stated by Robert above (or below maybe :-)), you could decorate the actions on a needs must basis to keep the intention clear, tho', i personally think the convention should show that up clearly.
certainly worthy of debate.
MVC 4 doesn't have an asynch controller - see the source:
namespace System.Web.Mvc
{
// Controller now supports asynchronous operations.
// This class only exists
// a) for backwards compat for callers that derive from it,
// b) ActionMethodSelector can detect it to bind to ActionAsync/ActionCompleted patterns.
public abstract class AsyncController : Controller
{
}
}
See my tutorial Using Asynchronous Methods in ASP.NET MVC 4
If you set a breakpoint in your Action method and observe the callstack (with Show External code enabled), you will see that there are several additional steps required to invoke a synchronous action residing in an AsyncController vs. in a standard Controller. Namely the AsyncControllerActionInvoker invokes Begin/End style methods ending with BeginInvokeSynchronousActionMethod. I don't know how much overhead these extra calls contribute, but it is something to be aware of before you blindly extend all your controllers from AsyncController even where no Async actions exist.
You should be fine doing that since AsyncController already inherits from Controller.
See here for more information
The remarks on that page are quite useful for determining whether you're doing the right thing by inheriting from AsyncController and offers a nice guide to keep you on track.
The use of an Async Controller depends on whether you want to wait for any particular task or step to complete before going on to the next task. The problem is akin to buying something from Amazon before the money from your paycheck hits your checking account.
For typical web applications, I would say this is not advisable. The web server is already very parallel, so the only advantage would be speeding up responsiveness to the user. For many operations this benefit would be negligible.
I would reserve the Async Controllers for long-running processes in the background, where it is impractical to wait for the task to complete before returning the web page back to the user's control.
NOTE: If you have a copy of a .NET disassembler (or the ASP.NET MVC source), you can open up the AsyncController class and have a look at the code. That should give you a pretty good idea whether or not you can use the AsyncController as an ordinary Controller.
The article I linked to below says this: "Controllers that derive from AsyncController enable ASP.NET to process asynchronous requests, and they can still service synchronous action methods."
http://msdn.microsoft.com/en-us/library/ee728598.aspx

How do I set up log4net for Asp.NET MVC application

We have a fist MVC application and I am wandering what special considerations there. In the regular web forms applications we pretty much just wrap events on code behind pages with try catch blocks. But it seems less clear with mvc as far as helpers, controllers, routes, etc. Where should I make sure there is logging.
Typically you would apply logging in your controller actions. You can also derive from the HandleError attribute to add error logging, as well as create custom action/result filters to automate certain types of logging. With such a filter, you can apply this to your base controller and have some basic usage logging/instrumentation for all actions.
If you customize the framework with controller factories, action invokers, or model binders, you might apply logging there as well. Of course, this is nothing to say of how to apply logging to your actual Model (domain objects, external services, persistence and database, security etc).
In your Global.asax.cs file:
protected void Application_Error(object sender, EventArgs e)
{
_logger.Error("Unhandled exception", Server.GetLastError());
}

Resources