Why to register HandleError in global.asax - asp.net-mvc-3

When a new MVC3 project is created, [HandleError] attribute is by default registered as GlobalFilter in GLobal.asax. However, if I comment it and execute following (with custom error mode on), it still works. I do see ErrorView with ErrorInfo model populated. Then what is the need for registering HandleError in Global.asax?
[HandleError(ExceptionType = typeof(NullReferenceException),View = "ErrorView")]
public ActionResult Index()
{
throw new NullReferenceException();
return View();
}

That is setting the default MVC exception handling policy. It will render the /Views/Shared/Error.cshtml view when an unhandled exception arises, without you having to explicitly add the HandleError attribute on every controller or action.
You can then add more specific HandleError attributes to your controller and\or actions, so you could display another error view than the default view or handle a more expecific exception type.
For the HandleError filters to work (global or not), you just need to make sure the custom errors are enabled in the web.config, as in <customErrors mode="On" /> (The default is RemoteOnly, so during development they won´t be executed)
This is nicely explained (following an example) here

Related

How can I disable alert message when the request is fail?

In some request, I need to change this alert to be somewhere on the screen, so how I can disable the default behavior when failing the request the alert show up by abp.message.error and I need to disable it and use another way.
You can send all exception details to the client easily. There's a setting for this purpose.
...
using Abp.Web.Configuration;
...
public override void PreInitialize()
{
Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true;
}
...
References:
Related Aspnet Boilerplate document
Throwing user friendly exception forum post
Related GitHub commit
Yet another related GitHub issue
Besides, you can disable exception handling for an application service or for an application service method. Just use [DontWrapResult] attribute for that.
public interface ITestAppService : IApplicationService
{
[DontWrapResult]
DoItOutput DoIt(DoItInput input);
}
See the related Aspnet Boilerplate docs

How to access session from a view in ASP .NET Core MVC 1.0

I am trying to access session data from inside a view.
Use Case: I'm storing status messages in the session that will be displayed at the top of the page. Currently I implemented this by using a DisplayMessages() function that sets some ViewData[....] properties and calling it at the beginning of every controller action.
Goal: I want to only set the status message once without needing additional code in the controller to display the messages on the next page load.
So I'm trying to access the messages that are stored in the session directly from the view.
So far I have tried the following:
Dependency Injection of an IHttpContextAccessor (doesn't seem to work anymore with ASP .NET Core MVC 1.0.0
Creating a static class to access the session, including the change from next() to next.invoke() suggested in the comment
This didn't work. I could access the HttpContext and Session.IsAvailable was true, but there was no data in the session.
The following should work in the view: Context.Session.TryGetValue
If you are using the SessionExtensions then Context.Session.GetString will work.
Injecting IHttpContextAccessor does work, but starting with ASP.NET Core 1.0.0 RC2, the IHttpContextAcessor is not registered by default, because it has significant performance overhead per request. See this GitHub announcement for more information.
Tratcher posted:
IHttpContextAccessor can be used to access the HttpContext for the current thread. However, maintaining this state has non-trivial performance costs so it has been removed from the default set of services.
Developers that depend on it can add it back as needed:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
But in your use case, I would suggest using a ViewComponent, which is a reusable piece of View with logic, that do not depend on a controller.
The documentation can be found here.
In your Views you would simply embed it with
#await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
or
#Component.Invoke("PriorityList", new { maxPriority = 2, isDone = false })
for synchronous calls.

IIS 7 Custom Error Page without Web.config

Is there any way to set a custom error page in IIS 7 without creating a web.config?
Unfortunately researching this particular topic has been very difficult because there are SO many articles on how to do it with a web.config. What I'm looking for is either buried beneath the 8 million results I don't want or it's not possible.
Yes, there is. It involves either subscribing to the Application_Error event in Global.asax or by writing a custom ErrorHandlerAttribute.
Darin already gave the correct answer, but I want to go into a little more depth.
In any ASP.NET application, given it is Web Forms, MVC, or raw ASP.NET, you can always use Application_Error Global.asax. If your ASP.NET application does not have a Global.asax, all you need to do is right-click your project in Solution Explorer, Add New Item, and choose Global Application Class. You should only have this option available if you don't already have one.
In your Global.asax, if you don't already see it, you can add Application_Error as shown below:
protected void Application_Error(object sender, EventArgs e) {
}
This will be called automatically by ASP.NET whenever there is an error. But as stated here, this is not perfect. Specifically:
An error handler that is defined in the Global.asax file will only
catch errors that occur during processing of requests by the ASP.NET
runtime. For example, it will catch the error if a user requests an
.aspx file that does not occur in your application. However, it does
not catch the error if a user requests a nonexistent .htm file. For
non-ASP.NET errors, you can create a custom handler in Internet
Information Services (IIS). The custom handler will also not be called
for server-level errors.
In Application_Error you can process the uncaught exception with Server.GetLastError(). This will provide you the Exception that was thrown, or null. I am not sure why this handler would be called if an exception didn't occur, but I believe that it is possible.
To redirect the user, use Response.Redirect(). Whatever you pass for the url is going to be sent directly to the browser without any further processing, so you can't use application-relative paths. To do that I would use this method in combination with VirtualPathUtility.ToAbsolute(). For example:
Response.Redirect( VirtualPathUtility.ToAbsolute( "~/Error.aspx" ) );
This redirect will be a 302 (temporary redirect) rather than a 301 (permanent), which is what you want in the case of handling errors. It's worth noting that this overload of Response.Redirect is the same as calling the overload Response.Redirect(url, endResponse: true). This method works by throwing an exception, which is not ideal in terms of performance. Instead, call Response.Redirect(url, false) immediately followed by Response.Complete​Request().
If you're using ASP.NET MVC, [HandleError] is also an option. Place this attribute on your Controller or on an Action within a controller. When this attribute is present, MVC will display the Error view, found in the ~/Views/Shared folder.
But you can make this even easier for yourself. You can automatically add this attribute to call Controllers in your project by creating a FilterConfig class in your project. Example:
public class FilterConfig {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new HandleErrorAttribute());
}
}
And then add FilterConfig.RegisterGlobalFilters( GlobalFilters.Filters ); to your Application_Start() in Global.asax.
You can read more about the HandleErrorAttribute at https://msdn.microsoft.com/en-us/library/system.web.mvc.handleerrorattribute(v=vs.118).aspx.
But as stated above, both of these methods will never cover absolutely all errors that can occur during the processing of your application. It's not possible to provide the best user experience for all possible errors without using Web.config or configuring IIS manually.

Catching server side ajax handling errors in browser

Let's say I have some ajax based component, whose handler in server throws for some reason an exception (e.g. programming error, can't access database). And basically server responds with internal server error or some such. How can I catch this situation in browser and display for examplen an error message somewhere.
When user clicks this link, the server will show an error page and the browser should detect based on http status code that something went wrong and somehow to react to it.
new AjaxLink<Link>("link") {
public void onClick(AjaxRequestTarget target) {
throw new RuntimeException();
}
}
See org.apache.wicket.settings.IExceptionSettings#getAjaxErrorHandlingStrategy.
There is an example of this at http://www.wicket-library.com/wicket-examples/ajax/links (failure and exception links).
Normally, Wicket Ajax classes like AjaxFallbackLink for example, have a method
updateAjaxAttributes(AjaxRequestAttributes attributes)
where you can register error handlers, that execute javascript within the browser.
Override this method, create an AjaxCallListener and call
AjaxCallListener listener = new AjaxCallListener();
listener.onFailure(ADD_JAVASCRIPT_TO_EXECUTE_HERE);
attributes.getAjaxCallListeners().add(listener);
see the documentation of
org.apache.wicket.ajax.attributes.AjaxCallListener.getFailureHandler(Component component)

SecurityException in Ninject.Web.MVC3 under medium trust even when UseReflectionBasedInjection = true [duplicate]

Using Ninject 2.2 with ASP.NET MVC 3.
I have a controller and some classes located in an external assembly which are registered by loading a NinjectModule from said assembly.
The models contain some validation properties. It seems Ninject is getting a security exception when a post action is done on an action which takes a model with validation attributes. Below is the exception:
"Attempt by method
'Ninject.Web.Mvc.Validation.NinjectDataAnnotationsModelValidatorProvider.GetValidators(System Web.Mvc.ModelMetadata,
System.Web.Mvc.ControllerContext,
System.Collections.Generic.IEnumerable`1)'
to access method
'System.Web.Mvc.DataAnnotationsModelValidator.get_Attribute()'
failed."
The inner exception simply states: System.Security.SecurityException: Request failed.
However, this works fine in full-trust permissions.
I attempted to create the container in the main assembly via
var kernel = new StandardKernel(new NinjectSettings() { UseReflectionBasedInjection = true });
but the issue still persists.

Resources