Last active
August 29, 2015 14:14
-
-
Save timw255/f0c10de9be1dcb98b0d6 to your computer and use it in GitHub Desktop.
Custom Errors Module - Proof of Concept
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protected void Application_Error(object sender, EventArgs e) | |
{ | |
// check to see if something horrible is going on... | |
if (Request.Headers["Custom-Error-Request"] != null) | |
{ | |
// looks like a request to grab an error page ended up here. let's bail. | |
return; | |
} | |
// get the last error | |
HttpException err = Server.GetLastError() as HttpException; | |
Server.ClearError(); | |
// try to skip using any other custom error settings | |
Response.TrySkipIisCustomErrors = true; | |
// check to see if we need to send back something pretty | |
var acceptsHtml = Request.Headers["Accept"].Contains("text/html"); | |
// we're on! | |
if (err != null && acceptsHtml) | |
{ | |
// get the language from the visitor's browser settings | |
string lang = (Request.UserLanguages ?? Enumerable.Empty<string>()).FirstOrDefault(); | |
var culture = CultureInfo.GetCultureInfo(lang); | |
// set the culture to match the browser language | |
Thread.CurrentThread.CurrentUICulture = culture; | |
PageManager pageManager = PageManager.GetManager(); | |
PageNode pNode = null; | |
// this is where we would put a manager to do some fancy lookups based on the error codes | |
switch (err.GetHttpCode()) | |
{ | |
case 404: | |
pNode = pageManager.GetPageNodes().Where(pN => pN.Title == "404").FirstOrDefault(); | |
break; | |
case 500: | |
default: | |
pNode = pageManager.GetPageNodes().Where(pN => pN.Title == "Generic").FirstOrDefault(); | |
break; | |
} | |
// grab the URL of the error page we're going to display to the visitor | |
string url = pNode.GetFullUrl(culture, true); | |
url = UrlPath.ResolveUrl(url, true, true); | |
// grab the entire HTML of the page | |
WebClient client = new WebClient { Encoding = Encoding.UTF8 }; | |
client.Headers.Add("Custom-Error-Request", ""); | |
string html = err.GetHttpCode().ToString(); | |
try | |
{ | |
html = client.DownloadString(url); | |
} | |
catch (WebException ex) | |
{ | |
// the error page is probably blowing up. maybe do some logging...or send an email? | |
} | |
// send back the the best response we got for the error and a status code | |
Response.Write(html); | |
Response.StatusCode = err.GetHttpCode(); | |
} | |
else if (err != null) | |
{ | |
// just fire back a basic message and the status | |
Response.Write(err.GetHttpCode().ToString()); | |
Response.StatusCode = err.GetHttpCode(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<customErrors mode="On"> | |
<error statusCode="404" redirect="~/8ec96125-02ce-47e2-a545-0eba4192dc7d" /> | |
</customErrors> | |
<httpErrors errorMode="Custom"> | |
<remove statusCode="404" subStatusCode="-1" /> | |
<error statusCode="404" prefixLanguageFilePath="" path="/CustomErrorPages/8ec96125-02ce-47e2-a545-0eba4192dc7d.aspx" responseMode="ExecuteURL" /> | |
</httpErrors> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I hadn't thought about the accept header thing, good call.
The language sniffing was done because I want to grab the page and return it under the same URL, along with the error code. Because I'm not doing a redirect (spinning up the WebRequest manually) I didn't think I could rely on Sitefinity to return the correct page. I admit that I might be over-complicating it though. 😄
If WebClient is faster and returns the same result, I'm totally making the switch.