ASP.NET MVC 5 - 错误处理 - 找不到 404 页面
ASP.NET MVC 5 - Error Handle for - 404 Page not found
对于标准错误,我使用解决方案错误句柄(见下面的代码),我也尝试了 THIS(没有效果)
Global.asax.cs
protected void Application_Error(object sender, EventArgs e)
{
var exception = Server.GetLastError();
var httpException = exception as HttpException;
var routeData = new RouteData();
routeData.Values.Add("controller", "Error");
if (httpException == null)
routeData.Values.Add("action", "Index");
else //It's an Http Exception, Let's handle it.
switch (httpException.GetHttpCode())
{
case 404:
// Page not found.
routeData.Values.Add("action", "HttpError404");
break;
case 500:
// Server error.
routeData.Values.Add("action", "HttpError500");
break;
// Here you can handle Views to other error codes.
// I choose a General error template
default:
routeData.Values.Add("action", "General");
break;
}
// Pass exception details to the target error View.
routeData.Values.Add("error", exception);
var request = Request;
// Pass request details to the target request View.
routeData.Values.Add("request", request);
// Clear the error on server.
Server.ClearError();
// Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(
new HttpContextWrapper(Context), routeData));
}
错误控制器
public class ErrorController : Controller
{
private readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// GET: Error
public ActionResult Index()
{
return View();
}
public ActionResult HttpError404(string error, HttpRequest request)
{
ViewBag.Title = "Page not found (Error 404)";
ViewBag.Description = error;
return View("~/Views/Shared/Error.cshtml");
}
public ActionResult HttpError500(string error, HttpRequest request)
{
ViewBag.Title = "Internal server error (Error 500)";
ViewBag.Description = error;
return View("~/Views/Shared/Error.cshtml");
}
public ActionResult General(string error, HttpRequest request)
{
ViewBag.Title = "Internal server error";
ViewBag.Description = error;
return View("~/Views/Shared/Error.cshtml");
}
}
Error.cshtml
@{
Layout = "_Layout.cshtml";
}
<div class="row">
<div class="exceptionmessage col-md-12 text-center">
<div class="center-block">
<img src="~/Content/i/404.png" class="img-responsive"/>
</div>
<strong>@ViewBag.Message</strong>
<span class="center-block small text-uppercase">@ViewBag.Main</span>
<div class="center-block">@Html.ActionLink("Return to the Homepage", "Index", "Home", null, new {@class = "btn btn-primary"})</div>
</div>
</div>
我有一个目录 Techs
,其中有一些 XML 文件(用于加载数据,类似于本地数据库),并且在 web.config
中使用此脚本我禁用了对此的访问文件夹并从此文件夹下载文件(或者当我写不存在的 URL 或类似文件 www.test.com/afsdfgsdfg.pdf
时),我收到 IIS 消息 404 Page not found 没有从错误处理程序代码重定向到我的自定义错误 404 页面下面。
<system.web>
<customErrors mode="On" defaultRedirect="~/Error">
<error redirect="~/Error/HttpError404" statusCode="404" />
</customErrors>
</system.web>
<system.webServer>
<security xdt:Transform="Replace">
<requestFiltering>
<hiddenSegments>
<add segment="Techs" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
有什么方法可以处理所有 404 页面未找到的错误(同一页面而不是两个不同的页面)?
谢谢
编辑:
我为 ErrorController
添加了一条新路线到 RouteConfig.cs
:
routes.MapRoute("Error",
"{controller}/{action}/",
new { controller = "Error", action = "HttpError404" });
之后我将 web.config
更改为:
<customErrors mode="On" defaultRedirect="~/Error/General">
<error redirect="~/Error/HttpError404" statusCode="404" />
<error redirect="~/Error/HttpError500" statusCode="500" />
</customErrors>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error
statusCode="404"
path="/Error/HttpError404"
responseMode="ExecuteURL"/>
</httpErrors>
但它仍然不起作用,我收到 HTTP 错误 404.0 - 未找到 或 HTTP 错误 403.14 - 禁止 和类似的消息,例如,当我写的时候:
- web.com/Techs/
- web.com/Techs/catalog.csv
- web.com/Techs.pdf -> 重定向到 404 页面
- web.com/Home/c.pdf
在web.config中添加这一行
<system.web>
<customErrors mode="On" defaultRedirect="~/ErrorHandler/Index">
<error statusCode="404" redirect="~/ErrorHandler/NotFound"/>
</customErrors>
<system.web/>
编辑:
这应该涵盖该代码的所有错误......但我看到你已经有了。
您可以在主目录中创建一个名为 Error 的文件夹,然后用您自己的设计在那里创建一个 html 错误页面。
在您的网络配置中,添加:
<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="/Error/404.html" />
</customErrors>
这将重定向到错误文件夹中的 404.html。
如果你想检查控制器中的特定错误并重定向到相关的错误页面,你可以在控制器中创建一个 ErrorController 和不同类型的视图您要在 Error views 文件夹中检查的错误。例如:
//In the ErrorController
// GET: /Error/404 Bad request
public ActionResult E404()
{
return View();
}
并且在控制器中,如果找不到页面或 id == null,您可以执行以下操作:
if (id == null)
{
return RedirectToAction("E404", "Error");
}
我的有效解决方案
我没有向 RouteConfig.cs 添加任何新路由,只编辑下面的文件。我在没有参数的情况下调用方法的控制器,我受到了不同的对待。 Global.asax.cs 和 ErrorController 使用同上。
Web.config
<system.web>
<customErrors mode="On" defaultRedirect="~/Error/General">
<error redirect="~/Error/HttpError404" statusCode="403" />
<error redirect="~/Error/HttpError404" statusCode="404" />
<error redirect="~/Error/HttpError500" statusCode="500" />
</customErrors>
</system.web>
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="403" />
<remove statusCode="404" />
<remove statusCode="500" />
<error
statusCode="403"
path="/Error/HttpError404"
responseMode="ExecuteURL" />
<error
statusCode="404"
path="/Error/HttpError404"
responseMode="ExecuteURL" />
<error
statusCode="500"
path="/Error/HttpError500"
responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
对于标准错误,我使用解决方案错误句柄(见下面的代码),我也尝试了 THIS(没有效果)
Global.asax.cs
protected void Application_Error(object sender, EventArgs e)
{
var exception = Server.GetLastError();
var httpException = exception as HttpException;
var routeData = new RouteData();
routeData.Values.Add("controller", "Error");
if (httpException == null)
routeData.Values.Add("action", "Index");
else //It's an Http Exception, Let's handle it.
switch (httpException.GetHttpCode())
{
case 404:
// Page not found.
routeData.Values.Add("action", "HttpError404");
break;
case 500:
// Server error.
routeData.Values.Add("action", "HttpError500");
break;
// Here you can handle Views to other error codes.
// I choose a General error template
default:
routeData.Values.Add("action", "General");
break;
}
// Pass exception details to the target error View.
routeData.Values.Add("error", exception);
var request = Request;
// Pass request details to the target request View.
routeData.Values.Add("request", request);
// Clear the error on server.
Server.ClearError();
// Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(
new HttpContextWrapper(Context), routeData));
}
错误控制器
public class ErrorController : Controller
{
private readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// GET: Error
public ActionResult Index()
{
return View();
}
public ActionResult HttpError404(string error, HttpRequest request)
{
ViewBag.Title = "Page not found (Error 404)";
ViewBag.Description = error;
return View("~/Views/Shared/Error.cshtml");
}
public ActionResult HttpError500(string error, HttpRequest request)
{
ViewBag.Title = "Internal server error (Error 500)";
ViewBag.Description = error;
return View("~/Views/Shared/Error.cshtml");
}
public ActionResult General(string error, HttpRequest request)
{
ViewBag.Title = "Internal server error";
ViewBag.Description = error;
return View("~/Views/Shared/Error.cshtml");
}
}
Error.cshtml
@{
Layout = "_Layout.cshtml";
}
<div class="row">
<div class="exceptionmessage col-md-12 text-center">
<div class="center-block">
<img src="~/Content/i/404.png" class="img-responsive"/>
</div>
<strong>@ViewBag.Message</strong>
<span class="center-block small text-uppercase">@ViewBag.Main</span>
<div class="center-block">@Html.ActionLink("Return to the Homepage", "Index", "Home", null, new {@class = "btn btn-primary"})</div>
</div>
</div>
我有一个目录 Techs
,其中有一些 XML 文件(用于加载数据,类似于本地数据库),并且在 web.config
中使用此脚本我禁用了对此的访问文件夹并从此文件夹下载文件(或者当我写不存在的 URL 或类似文件 www.test.com/afsdfgsdfg.pdf
时),我收到 IIS 消息 404 Page not found 没有从错误处理程序代码重定向到我的自定义错误 404 页面下面。
<system.web>
<customErrors mode="On" defaultRedirect="~/Error">
<error redirect="~/Error/HttpError404" statusCode="404" />
</customErrors>
</system.web>
<system.webServer>
<security xdt:Transform="Replace">
<requestFiltering>
<hiddenSegments>
<add segment="Techs" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
有什么方法可以处理所有 404 页面未找到的错误(同一页面而不是两个不同的页面)?
谢谢
编辑:
我为 ErrorController
添加了一条新路线到 RouteConfig.cs
:
routes.MapRoute("Error",
"{controller}/{action}/",
new { controller = "Error", action = "HttpError404" });
之后我将 web.config
更改为:
<customErrors mode="On" defaultRedirect="~/Error/General">
<error redirect="~/Error/HttpError404" statusCode="404" />
<error redirect="~/Error/HttpError500" statusCode="500" />
</customErrors>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error
statusCode="404"
path="/Error/HttpError404"
responseMode="ExecuteURL"/>
</httpErrors>
但它仍然不起作用,我收到 HTTP 错误 404.0 - 未找到 或 HTTP 错误 403.14 - 禁止 和类似的消息,例如,当我写的时候:
- web.com/Techs/
- web.com/Techs/catalog.csv
- web.com/Techs.pdf -> 重定向到 404 页面
- web.com/Home/c.pdf
在web.config中添加这一行
<system.web>
<customErrors mode="On" defaultRedirect="~/ErrorHandler/Index">
<error statusCode="404" redirect="~/ErrorHandler/NotFound"/>
</customErrors>
<system.web/>
编辑: 这应该涵盖该代码的所有错误......但我看到你已经有了。
您可以在主目录中创建一个名为 Error 的文件夹,然后用您自己的设计在那里创建一个 html 错误页面。
在您的网络配置中,添加:
<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="/Error/404.html" />
</customErrors>
这将重定向到错误文件夹中的 404.html。
如果你想检查控制器中的特定错误并重定向到相关的错误页面,你可以在控制器中创建一个 ErrorController 和不同类型的视图您要在 Error views 文件夹中检查的错误。例如:
//In the ErrorController
// GET: /Error/404 Bad request
public ActionResult E404()
{
return View();
}
并且在控制器中,如果找不到页面或 id == null,您可以执行以下操作:
if (id == null)
{
return RedirectToAction("E404", "Error");
}
我的有效解决方案
我没有向 RouteConfig.cs 添加任何新路由,只编辑下面的文件。我在没有参数的情况下调用方法的控制器,我受到了不同的对待。 Global.asax.cs 和 ErrorController 使用同上。
Web.config
<system.web>
<customErrors mode="On" defaultRedirect="~/Error/General">
<error redirect="~/Error/HttpError404" statusCode="403" />
<error redirect="~/Error/HttpError404" statusCode="404" />
<error redirect="~/Error/HttpError500" statusCode="500" />
</customErrors>
</system.web>
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="403" />
<remove statusCode="404" />
<remove statusCode="500" />
<error
statusCode="403"
path="/Error/HttpError404"
responseMode="ExecuteURL" />
<error
statusCode="404"
path="/Error/HttpError404"
responseMode="ExecuteURL" />
<error
statusCode="500"
path="/Error/HttpError500"
responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>