我想为500、404和403显示一个自定义错误页面。以下是我所做的:
Enabled custom errors in the web.config as follows:
<customErrors mode="On"
defaultRedirect="~/Views/Shared/Error.cshtml">
<error statusCode="403"
redirect="~/Views/Shared/UnauthorizedAccess.cshtml" />
<error statusCode="404"
redirect="~/Views/Shared/FileNotFound.cshtml" />
</customErrors>
Registered HandleErrorAttribute as a global action filter in the FilterConfig class as follows:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomHandleErrorAttribute());
filters.Add(new AuthorizeAttribute());
}
Created a custom error page for each of the above messages. The default one for 500 was already available out of the box.
Declared in each custom error page view that the model for the page is System.Web.Mvc.HandleErrorInfo
对于500,它显示自定义错误页面。对其他人来说,则不然。
我是不是遗漏了什么?
当我阅读HandleErrorAttribute类的OnException方法中的代码时,它看起来并不是显示自定义错误的全部,而且它只处理500个。
我必须做什么来处理其他错误?
我目前的设置(在MVC3上,但我认为它仍然适用)依赖于有一个ErrorController,所以我使用:
<system.web>
<customErrors mode="On" defaultRedirect="~/Error">
<error redirect="~/Error/NotFound" statusCode="404" />
</customErrors>
</system.web>
控制器包含以下内容:
public class ErrorController : Controller
{
public ViewResult Index()
{
return View("Error");
}
public ViewResult NotFound()
{
Response.StatusCode = 404; //you may want to set this to 200
return View("NotFound");
}
}
视图就是你实现它们的方式。不过,我倾向于添加一些逻辑,以便在应用程序处于调试模式时显示堆栈跟踪和错误信息。所以错误。CSHTML看起来像这样:
@model System.Web.Mvc.HandleErrorInfo
@{
Layout = "_Layout.cshtml";
ViewBag.Title = "Error";
}
<div class="list-header clearfix">
<span>Error</span>
</div>
<div class="list-sfs-holder">
<div class="alert alert-error">
An unexpected error has occurred. Please contact the system administrator.
</div>
@if (Model != null && HttpContext.Current.IsDebuggingEnabled)
{
<div>
<p>
<b>Exception:</b> @Model.Exception.Message<br />
<b>Controller:</b> @Model.ControllerName<br />
<b>Action:</b> @Model.ActionName
</p>
<div style="overflow:scroll">
<pre>
@Model.Exception.StackTrace
</pre>
</div>
</div>
}
</div>
这是我的解决方案。使用[ExportModelStateToTempData] / [ImportModelStateFromTempData]在我看来是不舒服的。
~ Views / Home / Error.cshtml:
@{
ViewBag.Title = "Error";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Error</h2>
<hr/>
<div style="min-height: 400px;">
@Html.ValidationMessage("Error")
<br />
<br />
<button onclick="Error_goBack()" class="k-button">Go Back</button>
<script>
function Error_goBack() {
window.history.back()
}
</script>
</div>
~ /控制器/ HomeController.sc:
public class HomeController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult Error()
{
return this.View();
}
...
}
~ /控制器/ BaseController.sc:
public class BaseController : Controller
{
public BaseController() { }
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result is ViewResult)
{
if (filterContext.Controller.TempData.ContainsKey("Error"))
{
var modelState = filterContext.Controller.TempData["Error"] as ModelState;
filterContext.Controller.ViewData.ModelState.Merge(new ModelStateDictionary() { new KeyValuePair<string, ModelState>("Error", modelState) });
filterContext.Controller.TempData.Remove("Error");
}
}
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
{
if (filterContext.Controller.ViewData.ModelState.ContainsKey("Error"))
{
filterContext.Controller.TempData["Error"] = filterContext.Controller.ViewData.ModelState["Error"];
}
}
base.OnActionExecuted(filterContext);
}
}
~ /控制器/ MyController.sc:
public class MyController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult Details(int id)
{
if (id != 5)
{
ModelState.AddModelError("Error", "Specified row does not exist.");
return RedirectToAction("Error", "Home");
}
else
{
return View("Specified row exists.");
}
}
}
祝你们项目成功;-)
在网络上。在系统下添加此配置。Webserver标签如下所示,
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404"/>
<remove statusCode="500"/>
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound"/>
<error statusCode="500" responseMode="ExecuteURL"path="/Error/ErrorPage"/>
</httpErrors>
并添加控制器为,
public class ErrorController : Controller
{
//
// GET: /Error/
[GET("/Error/NotFound")]
public ActionResult NotFound()
{
Response.StatusCode = 404;
return View();
}
[GET("/Error/ErrorPage")]
public ActionResult ErrorPage()
{
Response.StatusCode = 500;
return View();
}
}
加上他们受人尊敬的观点,我想这对所有人都肯定有效。
这个解决方案是我从《Neptune Century》中找到的