Am currently using mvc4 with vs2012 and i installed mvc.elmah nugget and am done.
What i did ?
Initially i didnt write any code and my exception were logged in ELMAH.
Later i decided to use MVC HandleError to handle Application Exceptions and added filter
filters.Add(new HandleErrorAttribute());
Now i debugged in filters and see i have 2 filters one for ELMAH HandleErrorAttribute and MVC HandleErrorAttribute !
I saw this excellent link https://stackoverflow.com/a/5936867/1481690 which talks about using ErrorSignal to handle Application Exceptions
But am not using ErrorSignal but still my Exceptions are captured by ELMAH ?
If i use
if (context.ExceptionHandled)
ErrorSignal.FromCurrentContext().Raise(context.Exception);
My Exceptions are logged twice.
My Question as follows
Do i need to use 2 filters(ELMAH and MVC) ?
If ELMAH is already having HandleErrorAttribute and log exception. Do i need to add MVC HandleErrorAttribute ?
What am doing currently is
Added filters
filters.Add(new HandleErrorAttribute());
and overriding (To handle Ajax Error in future)
public class HandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
public override void OnException(ExceptionContext context)
{
base.OnException(context);
}
Is this enough or what is the good practise ? Am not raising ErrorSignal as it is logging twice.
Am not using any try.catch as am using below line and hope my exception is handled.
base.OnException(context);
}
Just want to make sure that am on right way !
Thanks for the time
UPDATE: I pointed to the wrong package updating question.
You don't need both. ElmahHandleErrorAttribute inherits from HandleErrorAttribute, so using both is redundant.
How to get ELMAH to work with ASP.NET MVC [HandleError] attribute?
You also do not need to raise any signals for Elmah, the ElmahHandleErrorAttribute handles this.
If you're using Elmah.Contrib.MVC from Nuget all you need is ElmahHandleErrorAttribute.
filters.Add(new Elmah.Contrib.MVC.ElmahHandleErrorAttribute());
There's also a package on there that I mistook for this one at Elmah.MVC done by the same author as Elmah, I'm looking into this one to find out what the differences are and how to use it.
UPDATE 2: Ok, so apparently the Elmah.MVC package has all of this built in, and they register pretty much everything for you using WebActivator. So literally all you need to do on a brand new MVC project to start tracking errors with Elmah is to install the package, and compile. Done. However you should check your web.config after installing it, and under AppSettings, set the role required to view the page and enable the authentication.
I believe the way you have it is correct. This is in my Global.asax.cs
private static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ElmahHandleErrorAttribute());
filters.Add(new HandleErrorAttribute());
}
One thing to check is that your controllers do not have either [ElmahHandleError] or [HandleError] attributes.
Related
I'm trying to implement MvcSiteMapProvider with my new MVC4 website, but I've run into something that I can't seem to fix.
I setup authorization with Active Directory (no role provider currently), and everything was working as it should. When you try to get to any page other than the login page, you're redirected to the login page. The Account controller's action methods have the [allowAnonymous] attribute to allow unauthenticated users to access them so that they can login.
For some unknown reason, adding MvcSiteMapProvider to the project stops this from working and now unauthenticated users can get to any page. The Menu that MvcSiteMapProvider creates works correctly and only authenticated users can see it, but if the unauthenticated user types in a direct link they aren't redirected to the login page as they used to be.
I've removed MvcSiteMapProvider from the project and authentication started to work correctly again.
I believe this has something to do with MvcSiteMapProvider overridding the authorizeAttribute filter in some way, but I can't figure out where/how.
I can put [Authorize] on top of the controller and the redirect works with MvcSiteMapProvider, but that's against the whole reason for using MVC4.
//this is supposed to set authorize for the entire app
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new System.Web.Mvc.AuthorizeAttribute());
}
I have a feeling this issue is coming from MvcSiteMapProvider/External/AuthorizeAttributeBuilder.cs, but I'm not experienced enough to figure this out.
UPDATE:
Turns out that I had just setup my global filters incorrectly. For some reason that RegisterGlobalFilters method was in my global.asax file, so my FilterConfig.cs file didn't have the line:
filters.Add(new System.Web.Mvc.AuthorizeAttribute());
I removed the method from my global.asax file then updated the FilterConfig.cs file with the above filter and everything is now working as expected. Not sure how I got into this situation, but I'm glad I figured it out.
Someone on the mvcSiteMapProvider GitHub project had mentioned that he had MVC4 and mvcSiteMapProvider working seamlessly, so I created a new MVC4 app and added the mvcSiteMapProvider before making any changes and then added the authorize global filter. Everything worked as expected, so I compared projects and found where I had gone wrong. Hopefully this info helps someone, but I doubt it as it's a pretty unique case.
Turns out that I had just setup my global filters incorrectly. For some reason that RegisterGlobalFilters method was in my global.asax file, so my FilterConfig.cs file didn't have the line:
filters.Add(new System.Web.Mvc.AuthorizeAttribute());
I removed the method from my global.asax file then updated the FilterConfig.cs file with the above filter and everything is now working as expected. Not sure how I got into this situation, but I'm glad I figured it out.
Someone on the mvcSiteMapProvider GitHub project had mentioned that he had MVC4 and mvcSiteMapProvider working seamlessly, so I created a new MVC4 app and added the mvcSiteMapProvider before making any changes and then added the authorize global filter. Everything worked as expected, so I compared projects and found where I had gone wrong. Hopefully this info helps someone, but I doubt it as it's a pretty unique case.
I'm coming at the end of the development of my application.
Everything is working fine, but if once somebody got an unexpected exception, I would like to be able to:
Redirect him to a user-friendly page explaining that we got a problem.(Specifying a controller/action)
Log every information of the stack trace, current controller/action, parameter, session data, ...
What is the best way to do it with asp.net MVC?
EDIT
In complement of the great answer:
I integrated elmah like described here: http://joel.net/logging-errors-with-elmah-in-asp.net-mvc-3--part-1--setup
And then I specified some custom error page. So now I've all I need!
I would recommend you use "Elmah" http://code.google.com/p/elmah/
This package is a godsend - does exactly what is shown on the box, with close to ZERO changes to your source code.
It is also available via NuGet at http://nuget.org/packages/elmah
Use action filters.
http://blogs.msdn.com/b/gduthie/archive/2011/03/17/get-to-know-action-filters-in-asp-net-mvc-3-using-handleerror.aspx
You can catch errors in the global.asax. There is a method protected void Application_Error(object sender, EventArgs e) where you can do what ever you want.
Take a look at PostSharp, neat and easy to use. Starter version available to use after free registration. NuGet package also available http://nuget.org/packages/PostSharp
I'm converting an application which uses MVC1 , Visul Studio 2008 and .Net 3.5 to an MVC3, .Net4 vs2010 application.
I got it basically working but I have to implement a few thing out to get it going along.
To force a logout when the user expired I used to have this code in Global.asax.cs
void Session_End(object sender, EventArgs e)
{
//Todo make this work with mvc3/.net4
//IFormsAuthentication FormsAuth = ObjectFactory.GetInstance<IFormsAuthentication>();
//FormsAuth.SignOut();
//Server.Transfer("~/AccessControl/AdLogin.aspx");
}
But it crashed after converting to .Net4/MVC3, looked like something it depended upon was not initialized yet.
I assume that I need to move it to a new event, any idea which? If not that how do I do this in the new environment.
It is an ugly solution but I wound up wrapping it in a structure map exception Try/Catch and swallowing the exception. I'd really like to find a better solution if anyone has one.
Cal-
I am trying to Catch exceptions and log it.
Presently I have written a Utility method and Passing the Exception to it in the catch block and finally logging the application using MS Enterprise Library 4.0.
I want to know is there any other better way to log errors.
Show exception message in the same view for some type of exceptions for rest navigate to error page.
If someone can help me on this!
Navish
You could try elmah for error logging if that is what you are looking for.
If you were rolling your own Exception logging you could create a base Controller class that overrides the OnException method
public class BaseController : Controller
{
protected override void OnException(ExceptionContext filterContext)
{
ExceptionPolicy.HandleException(filterContext.Exception, "MyPolicy");
base.OnException(filterContext);
}
}
Elmah
Elmah could be great option for you. It is easy to use, after installing nuget package is ready for use.
Custom logging with log4net etc.
If you want to log errors by your own, I recommend this example app: https://github.com/mholec/mvcexceptionhandler where is explained global logging with your favorite log tool (log4net, nlog, etc.)
Application Insights
Another and maybe the best way is to use Application Insights. Application Insights you can install quickly using NuGet and you will get great overview of your application errors, website availability and you can get more information about your users. This service is free.
I recommend ELMAH http://code.google.com/p/elmah/
You can get started very quickly with it by using Nuget to set it up.
http://nuget.codeplex.com/
Setup Nuget.
In vstudio ->
View -> Other Windows -> Package
Manager
List-Package -filter elmah
install-package elmah and
you're all set.
You can view the log just like trace.axd by going to http://mysite/elmah.axd
and manually throw errors to elmah like this:
try {
}
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
}
hope that helps,
-fs
I have implemented my own VirtualPathProvider for loading 'embedded' views.
This works very well when running from Visual Studio, but I get the 'The view not found' message when running on IIS6.
Is there anything missing in web.config, or could there be any other problem?
I have added some logging and it seems that even though I register the Custom VirtualPathProvider in Application_Start, the System.Web.Hosting.MapPathBasedVirtualPathProvider is still used.
For the combination Custom VPP + IIS6 + Precompiled site, we need to add the VPP from AppInitailize();
public static class AppStart
{
public static void
{
// code to be executed automatically by the framework
}
}
See also:
http://sunali.com/2008/01/09/virtualpathprovider-in-precompiled-web-sites/
Is yours not used at all? VirtualPathProviders operate in a stack so, in your VirtualPathProvider, you should notice that the base class member "Previous" is actually the instance of "MapPathBasedVirtualPathProvider".
If you:
Attach your debugger to IIS
Make a change in your web.config, then change it back, then save (to trigger an recycle) - while still attached!
Place a breakpoint in your VPP in FileExists
Hit a page
Does your VPP get hit? If so, it may be an issue that after the first request, MVCs ViewEngine caching is preventing your VPP from getting hit for additional requests...