asp.net – CustomErrors vs HttpErrors – 一个重大的设计缺陷?
|
我们可能知道,例如,What is the difference between customErrors and httpErrors?,CustomErrors是一种在Web应用程序中定义错误页面的旧方法,但这种方法存在一些问题 – 例如,如果您关心正确的http响应代码,因为CustomErrors的方法是重定向到错误页面而不是替换当前响应,它通过http状态代码破坏了通信的大部分语义完整性. HttpErrors是自IIS 7.0以来可用的新功能,它在服务器级而不是应用程序级运行,并且更适合以有效的方式处理错误响应,例如通过使用当前响应而不是重定向. 但是,如果我认为ASP.NET中的这些工件的基础结构今天看起来给我们带来了一些问题. 一个简单的配置作为例子 <httpErrors existingResponse="Auto" errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="/Error/E404" responseMode="ExecuteURL" />
</httpErrors>
我们将errorMode设置为Custom,因为我们想测试错误处理本身,并将existingResponse设置为Auto,这将引入依赖于Response.TrySkipIisCustomErrors的分支: > True:现有的错误响应将通过此模块未经处理,考虑到它的语义含义,这是完全合理的. 理想情况下,这将允许我们自己处理一些错误,例如当../product/id中的产品不存在时,我们可以手动返回特定的404页面,其中包含有关缺失产品的信息,并且仍然让HttpErrors模块处理所有错误休息像../products/namebutshouldbeid或只是../misspelledandunmatchableurl. 但是,据我所知,这是行不通的.原因在于内部方法System.Web.HttpResponse.ReportRuntimeError,它将在运行时错误(例如未找到控制器/操作)上调用,并且我们有一个如下所示的部分: // always try to disable IIS custom errors when we send an error
if (_wr != null) {
_wr.TrySkipIisCustomErrors = true;
}
if (!localExecute) {
code = HttpException.GetHttpCodeForException(e);
// Don't raise event for 404. See VSWhidbey 124147.
if (code != 404) {
WebBaseEvent.RaiseRuntimeError(e,this);
}
// This cannot use the HttpContext.IsCustomErrorEnabled property,since it must call
// GetSettings() with the canThrow parameter.
customErrorsSetting = CustomErrorsSection.GetSettings(_context,canThrow);
if (customErrorsSetting != null)
useCustomErrors = customErrorsSetting.CustomErrorsEnabled(Request);
else
useCustomErrors = true;
}
在第一次调试时我发现useCustomErrors设置为false,我无法理解为什么因为我知道我有一个有效的HttpError配置,因为它可以在我从控制器返回HttpNotFoundResult的地方工作. 然后我意识到这不是HttpErrors,而是较旧的CustomErrors.而CustomErrors显然不知道HttpErrors. 错误” 所以发生的事情是Response.TrySkipIisCustomErrors设置为true,因为没有定义CustomErrors,它返回详细的404响应.此时我们希望HttpErrors启动,但它不会因为TrySkipIisCustomErrors现在设置为true. 我们也不能使用CustomErrors,因为这会让我们回到令人反感的错误重定向问题. 返回HttpNotFoundResult的原因是因为它不会触发运行时错误,只返回HttpErrors将按预期拦截的404结果,只要我们避免将Response.TrySkipIisCustomErrors设置为true即可. 应该如何处理/解决这个问题? 我认为默认情况下不允许System.Web.HttpResponse.ReportRuntimeError将Response.TrySkipIisCustomErrors设置为true,因为我们有另一个依赖于此的错误处理模块.因此,此方法也需要了解任何HttpErrors配置,或者通过避免将TrySkipIisCustomErrors设置为true(如果我们有任何CustomErrors配置),或者它与CustomErrors配置一起处理HttpErrors配置. 或者我错过了一些秘密魔法来解决这个问题? 解决方法就像你一样,我认为ASP.NET不应该设置TrySkipIisCustomErrors或者可以添加一个选项,以便我们可以避免它.作为一种解决方法,我构建了一个能够将查询传输到ASP.NET MVC控制器的ASPX页面. ErrorHandler.aspx.cs <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ErrorHandler.aspx.cs" Inherits="Guillaume.ErrorHandler" %> 代码背后 protected void Page_Load(object sender,EventArgs e)
{
//Get status code
var queryStatusCode = Request.QueryString.Get("code");
int statusCode;
if (!int.TryParse(queryStatusCode,out statusCode))
{
var lastError = Server.GetLastError();
HttpException ex = lastError as HttpException;
statusCode = ex == null ? 500 : ex.GetHttpCode();
}
Response.StatusCode = statusCode;
// Execute a route
RouteData routeData = new RouteData();
string controllerName = Request.QueryString.Get("controller") ?? "Errors";
routeData.Values.Add("controller",controllerName);
routeData.Values.Add("action",Request.QueryString.Get("action") ?? "Index");
var requestContext = new RequestContext(new HttpContextWrapper(Context),routeData);
IController controller = ControllerBuilder.Current.GetControllerFactory().CreateController(requestContext,controllerName);
controller.Execute(requestContext);
}
在web.config中的用法 <configuration>
<system.web>
<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="/Content/ErrorHandler.aspx">
<error statusCode="404" redirect="/Content/ErrorHandler.aspx?code=404&controller=Errors&action=NotFound" />
</customErrors>
</system.web>
</configuration>
常规浏览器请求的行为是正确的:当出现错误并返回错误代码时,将显示错误页面. 如果要将非ASP.NET错误重定向到自定义错误,可以添加httpErrors部分. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-core – JsonConvert DataSet .NET Core 2.0无效
- asp.net-mvc – ASP.NET MVC 3 – 将复杂的JSON模型发布到操
- asp.net-mvc-5 – 什么是XsrfKey用于,我应该将XsrfId设置为
- asp.net中让Repeater和GridView支持DataPager分页
- asp.net-mvc – 如何在我的MVC应用程序有机会处理之前如何阻
- RSS2.0中文规范详解及示例
- asp.net-mvc – 如何在ASP.NET MVC中禁用客户端和代理缓存?
- asp.net-mvc-3 – 如何使用Console.WriteLine在ASP.Net MVC
- asp.net-core – 在定位.NET Core时引用旧的(完整的.NET Fr
- asp.net-mvc – 传统的ASP.NET Web窗体与MVC
- asp.net-mvc-3 – 是否可以强制使用DataType作为
- asp.net-mvc – IIS 7.0不显示自定义错误页面
- asp.net – 表单验证忽略默认文档
- asp.net – 用于分析在azure上运行的网站性能的步
- asp.net – Combres的路线(combres.axd)不起作用
- asp.net-mvc – 将索引设置为控制器的默认路由
- asp.net-mvc – 如何在Html.RenderAction(MVC3)中
- asp.net – BC30560:’ExtensionAttribute’在名
- iis-6 – 如何防止IIS覆盖我在ASP.NET中设置的文
- asp.net – 在不使用HttpRequest的情况下获取主机
