catching exception thrown By CustomAuthorizeAttribute ASP.NET MVC 4 - c#

Suppose I have A CustomAuthorizeAttribute and I thew Exception in HandleUnauthorizedRequest. Is there any way to catch that exception and format the message and display it to the user. If not than how should a thing like this be implemented.

Do you want to do this globally? Or on a per controller basis?
If Globally, then you can create your own HandleErrorAttribute which will catch any unhandled exceptions. You can then test if the exception is HandleUnauthorizedRequest or not.
If you want to do this on a per controller basis, then you can override OnException and handle it there.

Related

Can you access the controller name from within a webapi ExceptionHandler or ExceptionLogger

I'm using a webapi ExceptionHandler and ExceptionLogger to ensure consistent logging and handling of exceptions at the controller level in my web api projects.
I want to log the controller name in which the exception occurred but I find that the ActionContext and ControllerContext are always null even when the exception is originating in a controller during a request.
The documentation Here states (underneath the ExceptionContext class) that
When the framework calls an exception logger or an exception handler, it will always provide an Exception and a Request. Except for unit testing, it will also always provide a RequestContext. It will rarely provide a ControllerContext and ActionContext (only when calling from the catch block for exception filters).
Is there an alternate way of being able to log the Controller Class Name from within the Handler / Logger?
Use the format below:
new ExceptionResult(ex, controller)
where ex is the exception and controller is the controller name

Any way to try catch whole Controller?

I got many Actions in my controller. Is there any way to try-catch whole Controller-document once instead inserting try-catch in every single action?
you could override the OnException method
protected override void OnException(ExceptionContext filterContext)
{
//your handling logic here
filterContext.ExceptionHandled = true;
}
Yes, you can capture the Application_Error event, which will handle all exceptions that are not handled by a the action code. For more information see this article.
If you want to catch any exception in all controllers in your MVC Application, then go for Global Exception Filters, this is a link that explains exactly how to catch and log global exceptions into database
http://www.dotnetcurry.com/aspnet-mvc/1260/exception-handling-logging-aspnet-mvc

Using of HandleErrorAttribute in ASP.NET MVC application

I have a question about the best way of using HandleErrorAttribute in my MVC 5 application.
As we know, we can add this attribute to global filters like that:
filters.Add(new HandleErrorAttribute{View = "Error"});
This involves the app to show the 'Error' view every time when an unhandled exception is thrown in any level of app.
But, if I have some logic in another global authorize or action filter, that produces some exception, then when the exception is thrown for first time, the app tries to redirect to the Error View, again other filters begin executing and produce the same exception again, so asp.net to avoid looping terminates the app.
So what is the best way to use this HandleErrorAttribute to avoid such behavior?
Thanks!
Edit:
After some debugging I found that this is not the usual behavior of HandleErrorAttribute, so looping happens for me only when I use custom Routes f.e.
{key}/{controller}/{action}
and when some error occurs in the filter logic, then the app tries to redirect to the Error View, but again another filter logic begins to exectue and I even see an "Error" value in the {key} route parameter, so it is unwanted behavior.
When I use the default route {controller}/{action}
this doesn't happen and I get exactly to the Error View without executing any global filter logic a second time.
You should wrap your action filter logic inside a try catch, then inside the catch block, redirect to the Error view and pass the Exception.
Your only other alternative is to ditch HandleError completely and use the Application_Error event inside Global.asax to manage your error handling. That way you can redirect to your Error action inside there regardless of where the error occured.
Matt is right about global.asax... this is the example I followed
http://www.digitallycreated.net/Blog/57/getting-the-correct-http-status-codes-out-of-asp.net-custom-error-pages
Then in each view I added: Response.StatusCode = 500; or which ever other code I wanted to show back to the client.

Exception handling in Controller (ASP.NET MVC)

When an exception is thrown by your own code that's called from an action in a controller how should that be handled? I see a lot of examples of best practices where there are no try-catch statements at all. For example, accessing data from a repository:
public ViewResult Index()
{
IList<CustomModel> customModels = _customModelRepository.GetAll();
return View(customModels);
}
Clearly this code could throw an exception if the call is to a database that it can't access and we are using an ORM like Entity Framework for example.
However all that I can see will happen is that the exception will bubble up and show a nasty error message to the user.
I'm aware of the HandleError attribute but I understand it's mostly used to redirect you to an error page if an exception that's unhandled occurs.
Of course, this code could be wrapped in a try-catch but doesn't separate nicely, especially if you have more logic:
public ViewResult Index()
{
if (ValidationCheck())
{
IList<CustomModel> customModels = new List<CustomModel>();
try
{
customModels = _customModelRepository.GetAll();
}
catch (SqlException ex)
{
// Handle exception
}
if (CustomModelsAreValid(customModels))
// Do something
else
// Do something else
}
return View();
}
Previously I have extracted out all code that could throw exceptions like database calls into a DataProvider class which handles errors and returns messages back for showing messages to the user.
I was wondering what the best way of handling this is? I don't always want to return to an error page because some exceptions shouldn't do that. Instead, an error message to the user should be displayed with a normal view. Was my previous method correct or is there a better solution?
I do three things to display more user-friendly messages:
Take advantage of the global exception handler. In the case of MVC: Application_Error in Global.asax. Learn how to use it here: http://msdn.microsoft.com/en-us/library/24395wz3(v=vs.100).aspx
I subclass Exception into a UserFriendlyException. I do my very best in all of my underlying service classes to throw this UserFriendlyException instead of a plain old Exception. I always try to put user-meaningful messages in these custom exceptions. The main purpose of which is to be able to do a type check on the exception in the Application_Error method. For the UserFriendlyExceptions, I just use the user-friendly message that I've set deep down in my services, like "Hey! 91 degrees is not a valid latitude value!". If it's a regular exception, then it's some case I haven't handled, so I display a more generic error message, like "Oops, something went wrong! We'll do our best to get that fixed!".
I also create an ErrorController that is responsible for rendering user-friendly views or JSON. This is the controller whose methods will be called from the Application_Error method.
EDIT:
I thought I'd give a mention to ASP.NET Web API since it's closely related. Because the consumer of Web API endpoints won't necessarily be a browser, I like to deal with errors a little differently. I still use the "FriendlyException" (#2 above), but instead of redirecting to an ErrorController, I just let all my endpoints return some kind of base type that contains an Error property. So, if an exception bubbles all the way up to the Web API controllers, I make sure to stick that error in the Error property of API response. This error message will either be the friendly message that has bubbled up from the classes the API controller relies on, or it will be a generic message if the exception type is not a FriendlyException. That way, the consuming client can simply check whether or not the Error property of the API response is empty. Display a message if the error is present, proceed as usual if not. The nice thing is that, because of the friendly message concept, the message may be much more meaningful to the user than a generic "Error!" message. I use this strategy when writing mobile apps with Xamarin, where I can share my C# types between my web services and my iOS/Android app.
With Asp.Net MVC you can also override the OnException method for you controller.
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled)
{
return;
}
filterContext.Result = new ViewResult
{
ViewName = ...
};
filterContext.ExceptionHandled = true;
}
This allow you to redirect to a custom error page with a message that refer to the exception if you want to.
I used an OnException override because I have several projects referenes to one that have a Controller that handle errors:
Security/HandleErrorsController.cs
protected override void OnException(ExceptionContext filterContext)
{
MyLogger.Error(filterContext.Exception); //method for log in EventViewer
if (filterContext.ExceptionHandled)
return;
filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult
{
Data = new
{
Success = false,
Error = "Please report to admin.",
ErrorText = filterContext.Exception.Message,
Stack = filterContext.Exception.StackTrace
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
filterContext.ExceptionHandled = true;
}
All questions like this are not very constructive, because the answer is always "it depends", because there are so many ways of dealing with error handling.
Many people like to use the HandleError method, because any exception is basically non-recoverable. I mean, what are you going to do if you can't return the objects? You're going to show them an error anyways, right?
The question becomes, how you want to show them the error. If showing them an error page is acceptable, than HandleError works fine, and provides an easy place to log the error. If you're using Ajax or want something fancier, then you need to develop a way to do that.
You talk about a DataProvider class. That's basically what your Repository is. Why not build that into your repository?

Handle Exception .NET MVC Keeping form data

I am trying to handle all exceptions at my c# MVC application.
All controllers inherit from BaseController, so I thought I could override the OnException (protected override void OnException(ExceptionContext filterContext)).
But I donĀ“t want to redirect to an error page, what I would like to do is to go back to the page that originated the request keeping its state. So if I had a form with an input filled by user, after handling the exception I want to show back that form with its input with the information filled by user.
Note: not all views are strongly typed.
example:
USER: myuser <-- text entered in input tag
After handling exception I want to go back to previous view showing exception message.
USER: myuser <-- text entered in input tag
My exception message
Validation should not be treated as unhandled exceptions! Please read about Model Validation in ASP.NET MVC in order to handle this scenario.
Unhandled exception is, as its name suggests, something that occurs only in exceptional cases. An exceptional case is something that when it occurs your application cannot process the request. So it doesn't make sense to redirect to a known state because there's no state when an unhandled exception occurs. The best you could do in this case is log the exception for further analysis and redirect the user to a 500 error page informing him that something went wrong.
Conclusion:
Use Model Validation to handle validation logic
Use OnException for unhandled exceptions.

Categories

Resources