public void Execute(HttpErrorReporterContext context) { try { if (ExecuteUserController(context.HttpContext)) { return; } if (ExecuteUserView(context.HttpContext)) { return; } BuiltInViewRender.Render(context); } catch (Exception ex) { OneTrue.Report(ex, new { context.HttpStatusCodeName, context.HttpStatusCode }); } }
/// <summary> /// Build an ASPX or HTML file to be used as our error page. /// </summary> /// <param name="context">Context for OneTrueError</param> /// <returns>Complete string</returns> public static void Render(HttpErrorReporterContext context) { var url = new Uri(string.Format("{0}://{1}{2}", HttpContext.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Authority, HttpContext.Current.Request.Url.AbsolutePath)); var virtualPathOrCompleteErrorPageHtml = LoadDefaultErrorPage(context.HttpStatusCodeName); var sb = new StringBuilder(); var sw = new StringWriter(sb); if (virtualPathOrCompleteErrorPageHtml.EndsWith(".aspx")) { var request = new HttpRequest(null, url.ToString(), ""); var response = new HttpResponse(sw); var httpContext = new HttpContext(request, response); httpContext.Items["ErrorReportContext"] = context; httpContext.Items["Exception"] = context.Exception; var pageType = BuildManager.GetCompiledType(virtualPathOrCompleteErrorPageHtml); var pageObj = Activator.CreateInstance(pageType); var executeMethod = pageType.GetMethod("Execute", new Type[0]); // support for web pages in the future? if (executeMethod != null && false) { executeMethod.Invoke(pageObj, new object[0]); } var page = (Page)pageObj; page.ProcessRequest(httpContext); } else if (virtualPathOrCompleteErrorPageHtml.EndsWith(".html")) { //VirtualPathUtility.ToAbsolute is really required if you do not want ASP.NET to complain about the path. using ( var stream = VirtualPathProvider.OpenFile( VirtualPathUtility.ToAbsolute(virtualPathOrCompleteErrorPageHtml))) { stream.CopyTo(context.HttpContext.Response.OutputStream); } } else if (virtualPathOrCompleteErrorPageHtml.StartsWith("<")) { var page = virtualPathOrCompleteErrorPageHtml; page = page.Replace("$reportId$", context.ErrorId) .Replace("$URL$", VirtualPathUtility.ToAbsolute("~/OneTrueError/Submit/")); page = page.Replace("$ButtonText$", CanSubmit ? "Send and proceed" : "Back to homepage."); // Should not ask for permission, but we want to get email or details. if (!OneTrue.Configuration.UserInteraction.AskUserForPermission && (OneTrue.Configuration.UserInteraction.AskForEmailAddress || OneTrue.Configuration.UserInteraction.AskUserForDetails)) { page = page.Replace("$AllSendReport$", "checked"); } else { page = page.Replace("$AllSendReport$", ""); } if (context.HttpContext.Request.AcceptTypes != null) { var htmlIndex = GetAcceptTypeIndex(context.HttpContext, "text/html"); var jsonIndex = GetAcceptTypeIndex(context.HttpContext, "/json"); var xmlIndex = GetAcceptTypeIndex(context.HttpContext, "application/xml"); if (jsonIndex < htmlIndex && jsonIndex < xmlIndex) { page = string.Format( @"{{""error"": {{ ""msg"": ""{0}"", ""reportId"": ""{1}""}}, hint: ""Use the report id when contacting us if you need further assistance."" }}", context.Exception.Message, context.ErrorId); context.HttpContext.Response.ContentType = "application/json"; } else if (xmlIndex < jsonIndex && xmlIndex < htmlIndex) { page = string.Format( @"<Error ReportId=""{0}"" hint=""Use the report id when contacting us if you need further assistance"">{1}</Error>", context.ErrorId, context.Exception.Message); context.HttpContext.Response.ContentType = "application/xml"; } } context.HttpContext.Response.Write(page); } else { context.HttpContext.Response.Write( string.Format("Unsupported virtual uri: {0}, must be a .aspx (Page) or a .html", virtualPathOrCompleteErrorPageHtml)); } }