Is it possible to access SessionState in the Error event handler of a HttpModule following a 404?
Im trying to implement a consistent error handling mechanism for both full and partial postbacks using the technique described in this blog post,
ASP.NET Error Handling......
Instead of passing loads of parameters on the query string im trying to push the exception into session state and access it from the error page.
SessionState is never available at point I do my Server.Transfer (in error handler of HttpModule) so not available to error page.
Ive tried the trick of resetting the IHttpHandler to one with the IRequestSessionState interface but no joy.
Thanks in advance,
EDIT - The code of the IHttpModule error handler is,
void context_Error(object sender, EventArgs e)
{
try
{
var srcPageUrl = HttpContext.Current.Request.Url.ToString();
// If the error comes our handler we retrieve the query string
if (srcPageUrl.Contains(NO_PAGE_STR))
{
// Deliberate 404 from page error handler so transfer to error page
// SESSION NOT AVAILABLE !!!!
HttpContext.Current.ClearError();
HttpContext.Current.Server.Transfer(string.Format("{0}?ErrorKey={1}", ERROR_PAGE_URL, errorKey), true);
}
else
HttpContext.Current.Server.ClearError();
return;
}
catch (Exception ex)
{
Logging.LogEvent(ex);
}
}
Matt
public class ExceptionModule : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
}
/// <summary>
/// Init method to register the event handlers for
/// the HttpApplication
/// </summary>
/// <param name="application">Http Application object</param>
public void Init(HttpApplication application)
{
application.Error += this.Application_Error;
}
private void Application_Error(object sender, EventArgs e)
{
// Create HttpApplication and HttpContext objects to access
// request and response properties.
var application = (HttpApplication)sender;
var context = application.Context;
application.Session["errorData"] = "yes there is an error";
context.Server.Transfer("Error.aspx");
}
}
This should do the trick! works for me!
Related
I am a new developer.
I am working on an ASP .NET Core project with C # and using "try catch" for error handling. However, my project is getting heavy due to too many "try catch" and also the code gets a little confusing.
My question is whether it would be possible to create a "global class" or some other way to handle errors?
Yes you can.
Your question has already been answered in some capacity here
Here are four examples using different project types:
ASP.NET Core MVC by implementing a custom ExceptionFilterAttribute:
public class MyExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
Exception ex = context.Exception;
Logger.Error(ex);
}
}
[Route("api/[controller]")]
[MyExceptionFilter]
public class HomeController : Controller
{
// Action methods
}
ASP.NET MVC by overriding OnException in your controller:
protected override void OnException(ExceptionContext context)
{
if (context.ExceptionHandled)
{
return;
}
Logger.Error(context.Exception);
context.Result = RedirectToAction(MVC.Error.Application());
context.ExceptionHandled = true;
}
Windows Application by subscribing to UnhandledException event:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine(e.ExceptionObject.ToString());
}
Web Forms by adding Application_Error handler in global.asax:
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
Logger.Error(ex);
}
Absolutely the answer is yes if I. However it depends on what kind of projects you are doing. you can catch the unhandled exception in the global.cs by overriding method or create an Attribute class to catch exception.
In aspnet web API 4.6, I am getting 200 status code when 404 was expected. Following is the module that can reproduce this.
internal class HttpRequestLoggerModule : IHttpModule
{
/// <summary>
/// Initializes the module
/// </summary>
/// <param name="context">application initializing the module</param>
public void Init(HttpApplication context)
{
context.EndRequest += OnEndRequest;
}
private static void OnEndRequest(object sender, EventArgs e)
{
var application = (HttpApplication)sender;
// Why this is 200 for 404 requests where route was incorrect and no handler was found.
var statusCode = application.Context.Response.StatusCode;
}
}
This is hosted in IIS and seems like 404 is returned by IIS and http module gets executed after the fact. Is there any way to capture correct status in the http module?
Is there an equivalent for MVC.NET's OnActionExecuting in standard asp.NET? ?
I thought it would be Page_Load since OnActionExecuting would be called each time an action is executed (or the page loads). But I'm running into inheritance issues when I try to use Page_Load instead.
Since it is very difficult to make my solution work with a Page_Load I'm thinking I might not have the best ... solution.
Any thoughts on whether they are equivalent or close enough?
Background:
I'm converting a piece of an MVC3 application into a standard .NET to wrap in a SharePoint Web Part.
Here's the MVC code I'm trying to translate, as you can see its the user security bits I'm translating:
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
if (!SiteCacheProvider.ItemCached(enmCacheKey.SiteSetting)) {
if (filterContext.IsImplementedGeneralPrincipal()) {
IUserProfile userProfile = ((IGeneralPrincipal)filterContext.HttpContext.User).UserProfile;
SiteCacheProvider.ChangeSiteSetting(userProfile.SiteID);
}
}
base.OnActionExecuting(filterContext);
}
First, take on account that no Actions are in ASP.NET because the model is different (Event-Based) - There're no methods(actions) which you can decorate with Action Filters, it's all about the Page-Cycle events.
Second, In ASP.NET, you may use HTTP modules (HttpApplication.BeginRequest particularly) in order to intercept incoming requests to your application pages by adding your required logic.
From MSDN:
HTTP Modules use to intercept HTTP requests for modifying or utilize
HTTP based requests according to needs like authentication,
authorization, session/state management, logging, modifying Response,
URL rewriting, Error handling, Caching....
For example:
using System;
using System.Web;
using System.Collections;
public class HelloWorldModule : IHttpModule
{
public string ModuleName
{
get { return "HelloWorldModule"; }
}
public void Init(HttpApplication application)
{
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
application.EndRequest += (new EventHandler(this.Application_EndRequest));
}
private void Application_BeginRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("<h1>HelloWorldModule: Beginning of Request</h1><hr>");
}
private void Application_EndRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("<hr><h1>HelloWorldModule: End of Request</h1>");
}
public void Dispose()
{
}
}
I have an ASP.NET application and dll which extends IHttpModule. I have used the below method to save the session variables in httpcontext through
public class Handler : IHttpModule,IRequiresSessionState
{
public void Init(HttpApplication httpApp)
{
httpApp.PreRequestHandlerExecute += new EventHandler(PreRequestHandlerExecute);
}
public void PreRequestHandlerExecute(object sender, EventArgs e)
{
var context = ((HttpApplication)sender).Context;
context.Session["myvariable"] = "Gowtham";
}
}
and in my asp.net Default.aspx page I have used code to retrive value as
public partial class _Default : System.Web.UI.Page, IRequiresSessionState
{
protected void Page_Load(object sender, EventArgs e)
{
String token = Context.Session["myvariable"].ToString();
}
}
I am getting error response as
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
In order to ensure whether the variables store in session I have crossed check by following method in class handler after storing the value in session as
string ss = context.Session["myvariable"].ToString();
it well executed and retrieved the value from session.
Why do you need to use Context and not Session directly? From the code I can only assume that you are going to set a value in the Session, and then read the value on page load. Rather than you do something like that, you can do this:
Add a Global Application Class, Right click on your project, Add > New Item, choose Global Application Class, and on that file, insert the following code to initialize the value
protected void Session_Start(object sender, EventArgs e)
{
Session["myvariable"] = "Gowtham";
}
On the Page_Load, you can access by:
if ( Session["myvariable"] != null ) {
String token = Context.Session["myvariable"].ToString();
}
Hope this help..
use System.Web.HttpContext.Current.Session["myvariable"] in both parts
I have an website under which i have 5 files
test1.aspx
test2.aspx
test3.aspx
test4.aspx
test5.aspx
i have an http module which gets called in all the pages
but i have an condition where on test5.aspx page i do not want the http module to be called what settings need to be done in order to resolve the issue?
HttpModules get run before your page lifecycle, so you'd have to match it on the request path.
Assuming your HttpModule's Init function sets up a BeforeRequest handler, something like:
public class MyModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.BeginRequest += this.BeginRequest;
}
public void BeginRequest(object sender, EventArgs e)
{
var app = sender as HttpApplication;
if (app.Request.Path.Contains("test5.aspx")) {
return;
}
// Process logic for other pages here
}
}