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());
}
Related
Occasionally a developer will not instantiate a required part of a viewmodel and the corresponding razor view will throw a NullReferenceException error. From there, customErrors redirects to a generic server error 500 view.
I want to log that error in a repository so these incidents can be discovered and fixed. Is there part of the framework that can handle this?
You can use logging frameworks like ELMAH or LOGNet, which are great tools but sometimes you just want to shove it into a database or send a simple email. To manage something like that I have found the best solution is to create a base controller that all of your controllers will inherit from and override the following:
protected override async void OnException(ExceptionContext filterContext)
{
}
Anytime an exception handles in the view or in the controller it will hit here before doing anything. You can still even have other frameworks work with this also.
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.
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.
I want to handle application wide error and show a ErrorView page in asp.net mvc.
There are 3 ways to do it (or i know).
1) ErrorAttribute in BaseController:Controller class.
Can be used on individual Action/Controller/BaseController.
2) Override OnException() in the BaseController:Controller class.
Will work on Controllers derived from BaseController
3) Application_Error in Global_aspx.
What is the best practice.
Which one of these methods should be used for application wide error handling or should we use multiple or only one.
If we handle error on ErrorAttribute Or/And OnException() on BaseController should we still handle it in Application_Error().
When should we use Application_Error()?
HandleErrorAttribute is an MVC filter applied via the attribute. You can supply a view name to display if an exception occurs and you can also specify the base (or specific) type of exception this filter applies to. If no view name is supplied it will look for a view named "Error". As you've already noticed you can apply it to various scopes. It allows you to specify a different "error page" view based on the exception.
Controller.OnException is a method that will get called if any of your actions ends up throwing an error.
Both of the above two are MVC concepts and part of the MVC pipeline, which sits on top of the ASP.NET pipeline, and if you handle the exception using the above it won't propagate to Application_Error, but things like http errors 404, 500 and will if I remember correctly.
What to use?
Definitely look into ELMAH for application wide error logging and my blog post about ELMAH and ASP.NET MVC
Regarding displaying error pages you should be fine with just using [HandleError] and the HandleErrorAttribute, since it already handles everything for you (optional filtering and optional custom error page per exception type).
if you want to handle the error on application level then don't apply the HandleError or OnException Override for the controller.
Try to Get the Last Error from the Server Object in Application_Error Handler check the Exception Type and based on the exception type define the action you would like to perform.
For 404 you might want to set a different action on the controller to handle.
For 500 you might want to set a different action on the controller to handle.
For NON HTTPException (SQLException) you might even want to send out email.
Please make sure you set the correct Response Status Code for SEO purpose.
We know that behind the scenes, the ASP.NET MVC framework will use reflection to determine what controllers/actions are available to be executed, based on which classes derive from System.Web.Mvc.Controller and, of those classes, which methods return an ActionResult object.
To my question - is it possible to access this list of controllers/actions from within my MVC application?
(I could do it myself, by using reflection on the current assembly, but if the list has already been built by ASP.NET MVC, I'd rather re-use that effort than re-invent the wheel myself.)
new ReflectedControllerDescriptor(typeof(TController)).GetCanonicalActions() will return a collection of ActionDescriptor objects showing all the actions on the controller. It's not smart enough to understand things like selection attributes or naming attributes, so not every action it returns is guaranteed to be web-callable. But if you need to execute the actions directly, you can call ActionDescriptor.Execute() on any action of interest to you.
This is done in an internal class in the System.Web.Mvc assembly called System.Web.Mvc.ControllerTypeCache.
By the way, action methods are not required to return ActionResult. They can return void happily, for instance.