朋友問到一個問題,如何輸出自定義錯誤頁面,不使用302跳轉。目前頁面位址不能改變.
還要執行一些代碼等,生成一些錯誤資訊,友善使用者送出回報.
500錯誤,mvc架構已經有現成解決方法:
filters.Add(new HandleErrorAttribute());
404錯誤目前想到的解決方法:
先上代碼 Global.asax:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
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 }
28 }
View Code
controller代碼:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
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
<system.webServer>
<httpErrors errorMode="Detailed" />
目前有幾個疑惑,沒有深究:還望有網友知道能解惑一二,就不用去google 扒源碼了。
1.如果不加這行代碼,預設輸出的是:text/html; 浏覽器直接輸出内容,不做解析.
httpContext.Response.ContentType = "text/html; charset=utf-8";
2.iis不會使用gzip壓縮,不管輸出的404錯誤頁面有多大,都不會自動壓縮.是以使用下面這種替換方式.
[Compress]
public class SysController : Controller
猜測:
mvc 在action的Execute階段後 還做了不少事情,比如上面提到的1,2點.正常200請求會執行預設的filter等階段.
而當是404請求時,跳過了這些階段.可能500請求也類似.
僅僅是猜測,還未驗證,