using System;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Configuration;
using System.Web.Mvc;
using ApacKernel;
using Newtonsoft.Json;
namespace Now.Web.Modules
{
///
/// Enables support for CustomErrors ResponseRewrite mode in MVC.
///
public class ErrorHandlerModule : IHttpModule
{
private HttpContext HttpContext { get { return HttpContext.Current; } }
private CustomErrorsSection CustomErrors { get; set; }
public void Init(HttpApplication application)
{
//System.Configuration.Configuration configuration = WebConfigurationManager.OpenWebConfiguration("~");
//CustomErrors = (CustomErrorsSection)configuration.GetSection("system.web/customErrors");
CustomErrors = (CustomErrorsSection)ApacConfig.Sections.GetSection("system.web/customErrors");
application.EndRequest += Application_EndRequest;
}
protected void Application_EndRequest(object sender, EventArgs e)
{
// only handle rewrite mode, ignore redirect configuration (if it ain't broke don't re-implement it)
if (CustomErrors.RedirectMode == CustomErrorsRedirectMode.ResponseRewrite && HttpContext.IsCustomErrorEnabled)
{
var statusCode = HttpContext.Response.StatusCode;
// if this request has thrown an exception then find the real status code
var exception = HttpContext.Error;
if (exception != null)
{
// set default error status code for application exceptions
statusCode = (int)HttpStatusCode.InternalServerError;
}
var httpException = exception as HttpException;
if (httpException != null)
{
statusCode = httpException.GetHttpCode();
}
if ((HttpStatusCode)statusCode != HttpStatusCode.OK)
{
var errorPaths = CustomErrors.Errors.Cast().ToDictionary(error => error.StatusCode, error => error.Redirect);
// find a custom error path for this status code
if (errorPaths.Keys.Contains(statusCode))
{
string url = errorPaths[statusCode];
// avoid circular redirects
if (!HttpContext.Request.Url.AbsolutePath.Equals(VirtualPathUtility.ToAbsolute(url)))
{
HttpContext.Response.Clear();
HttpContext.Response.TrySkipIisCustomErrors = true;
HttpContext.Server.ClearError();
if (!new HttpRequestWrapper(HttpContext.Current.Request).IsAjaxRequest())
{
// do the redirect here
if (HttpRuntime.UsingIntegratedPipeline)
{
HttpContext.Server.TransferRequest(url, true);
}
else
{
HttpContext.RewritePath(url, false);
IHttpHandler httpHandler = new MvcHttpHandler();
httpHandler.ProcessRequest(HttpContext);
}
}
else if (exception != null)
{
HttpContext.Response.ContentType = "application/json";
HttpContext.Response.Write(JsonConvert.SerializeObject(exception));
}
// return the original status code to the client
// (this won't work in integrated pipleline mode)
HttpContext.Response.StatusCode = statusCode;
}
}
}
}
}
public void Dispose()
{
}
}
}