朋友問到一個問題,如何輸出自定義錯誤頁面,不使用302跳轉。當前頁面地址不能改變.html
還要執行一些代碼等,生成一些錯誤信息,方便用戶提交反饋.web
500錯誤,mvc框架已經有現成解決方法:瀏覽器
filters.Add(new HandleErrorAttribute());
404錯誤目前想到的解決方法:mvc
先上代碼 Global.asax:app

1 protected void Application_Error(object sender, EventArgs e) 2 { 3 var ex = Server.GetLastError() as HttpException; 4 if (ex == null) 5 return; 6 7 var httpStatusCode = ex.GetHttpCode(); 8 9 if (httpStatusCode == 404) 10 { 11 var httpContext = (sender as MvcApplication).Context; 12 13 httpContext.ClearError(); 14 httpContext.Response.Clear(); 15 httpContext.Response.StatusCode = 404; 16 ServiceFocus.LogService.AddLog(ex); 17 18 httpContext.Response.ContentType = "text/html; charset=utf-8"; 19 var routeData = new RouteData(); 20 routeData.Values["controller"] = "Sys"; 21 routeData.Values["action"] = "NotFound"; 22 var requestContext = new RequestContext(new HttpContextWrapper(httpContext), routeData); 23 var controller = ControllerBuilder.Current.GetControllerFactory().CreateController(requestContext, "Sys") as SysController; 24 //controller.ViewData.Model=model; 25 (controller as IController).Execute(requestContext); 26 ControllerBuilder.Current.GetControllerFactory().ReleaseController(controller); 27 }
controller代碼:

1 public class CompressAttribute : ActionFilterAttribute 2 { 3 public override void OnActionExecuting(ActionExecutingContext filterContext) 4 { 5 var acceptEncoding = filterContext.HttpContext.Request.Headers["Accept-Encoding"]; 6 if (!string.IsNullOrEmpty(acceptEncoding)) 7 { 8 acceptEncoding = acceptEncoding.ToLower(); 9 var response = filterContext.HttpContext.Response; 10 if (acceptEncoding.Contains("gzip")) 11 { 12 response.AppendHeader("Content-encoding", "gzip"); 13 response.Filter = new GZipStream(response.Filter, CompressionMode.Compress); 14 } 15 else if (acceptEncoding.Contains("deflate")) 16 { 17 response.AppendHeader("Content-encoding", "deflate"); 18 response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress); 19 } 20 } 21 } 22 } 23 [Compress] 24 public class SysController : Controller 25 { 26 // 27 // GET: /sys/ 28 29 public ActionResult NotFound() 30 { 31 return View(); 32 } 33 public ActionResult Error() 34 { 35 return View(); 36 } 37 }
web.config框架
啓用輸出錯誤信息,不然iss在外網請求的時候不會看到自定義的輸出的錯誤信息ide
<system.webServer>
<httpErrors errorMode="Detailed" />
</system.webServer>
目前有幾個疑惑,沒有深究:還望有網友知道能解惑一二,就不用去google 扒源碼了。post
1.若是不加這行代碼,默認輸出的是:text/html; 瀏覽器直接輸出內容,不作解析.ui
httpContext.Response.ContentType = "text/html; charset=utf-8";
2.iis不會使用gzip壓縮,無論輸出的404錯誤頁面有多大,都不會自動壓縮.因此使用下面這種替換方式.google
[Compress] public class SysController : Controller
猜想:
mvc 在action的Execute階段後 還作了很多事情,好比上面提到的1,2點.正常200請求會執行默認的filter等階段.
而當是404請求時,跳過了這些階段.可能500請求也相似.
僅僅是猜想,還未驗證,
更多: